From patchwork Tue Jun 25 18:42:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iyer, Balaji V" X-Patchwork-Id: 254287 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id C1AE42C0040 for ; Wed, 26 Jun 2013 04:42:54 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:content-type :mime-version; q=dns; s=default; b=kHOLkygCRDFlwQvyfLUZkwJWwXC2w GGh5b62+rveRIqzVQfci50Q8mV49qco3HItpm8yBLFe54CKbnMq4v91NgH7wlDYw MXxUl7m/X+Rekn/8p3iZhUIb/Lks/nD7MX8RR21uu0rJsg4j97U84SPofoQjNfau Z2NGBi/4PSios0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:content-type :mime-version; s=default; bh=zCe2PHeMlUqWCwm0WJbmDWrfSQY=; b=WsH qtJVtvyVpt5VnUkQey594+hefZu8yAKwYMusk67SsX7Br/hhDEtpMfQfpbiNUYNv NKIk7uCwDJ+PhEn9j7eTkp0uJ5/TeVRF5yD/no/dBxKEfhZUWhkAqcz/csT7Dhtb 6M/K5PvMPtCkmjQeQniNuoiHoFkucMb5IZxGpnnQ= Received: (qmail 25357 invoked by alias); 25 Jun 2013 18:42:45 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 25346 invoked by uid 89); 25 Jun 2013 18:42:45 -0000 X-Spam-SWARE-Status: No, score=-7.3 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD, SPF_PASS, TW_EG, TW_TM autolearn=ham version=3.3.1 Received: from mga09.intel.com (HELO mga09.intel.com) (134.134.136.24) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 25 Jun 2013 18:42:40 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 25 Jun 2013 11:40:08 -0700 X-ExtLoop1: 1 Received: from fmsmsx108.amr.corp.intel.com ([10.19.9.228]) by orsmga001.jf.intel.com with ESMTP; 25 Jun 2013 11:42:28 -0700 Received: from fmsmsx101.amr.corp.intel.com ([169.254.1.114]) by FMSMSX108.amr.corp.intel.com ([169.254.10.97]) with mapi id 14.03.0123.003; Tue, 25 Jun 2013 11:42:27 -0700 From: "Iyer, Balaji V" To: Jason Merrill , Richard Henderson CC: Aldy Hernandez , "gcc-patches@gcc.gnu.org" Subject: RE: [PATCH] Cilk Plus Array Notation for C++ Date: Tue, 25 Jun 2013 18:42:26 +0000 Message-ID: References: <51B8A2FA.2020404@redhat.com> <51B9EF1D.9060505@redhat.com> <51B9F0EA.50709@redhat.com> <51BF4222.3050107@redhat.com> <51C0F06E.3080507@redhat.com> <51C341D2.8020707@redhat.com> <51C5CEC9.8050309@redhat.com> <51C9AB76.606@redhat.com> MIME-Version: 1.0 X-Virus-Found: No Sorry, I accidentally clicked send before attaching the patch. I have attached the patch and the ChangeLogs for this. Thanks, Balaji V. Iyer. > -----Original Message----- > From: Iyer, Balaji V > Sent: Tuesday, June 25, 2013 2:28 PM > To: 'Jason Merrill'; Richard Henderson > Cc: Aldy Hernandez; gcc-patches@gcc.gnu.org > Subject: RE: [PATCH] Cilk Plus Array Notation for C++ > > > > > -----Original Message----- > > From: Jason Merrill [mailto:jason@redhat.com] > > Sent: Tuesday, June 25, 2013 10:39 AM > > To: Iyer, Balaji V; Richard Henderson > > Cc: Aldy Hernandez; gcc-patches@gcc.gnu.org > > Subject: Re: [PATCH] Cilk Plus Array Notation for C++ > > > > On 06/24/2013 06:23 PM, Iyer, Balaji V wrote: > > >> Actually, to reduce the amount of changes to non-AN code, let's put > > >> the AN case third, after the offset and {} cases, so you get > > >> something like > > >> > > >> else if (flag_enable_cilkplus) > > >> { > > >> tree an = cp_parser_array_notation (loc, parser, &index, > > >> postfix_expression); > > >> if (an) > > >> return an; > > >> /* Otherwise, cp_parser_array_notation set 'index'. */ > > >> } > > >> else > > >> index = cp_parser_expression (parser, /*cast_p=*/false, NULL); > > >> > > >> this way the change is just a few added lines, and everything else > > >> is in cp_parser_array_notation. > > > > > If I do it this way, then I don't think I will be able to handle a > > > normal array > > reference when cilk plus is enabled. > > > > What I had in mind is that in the case of a normal array reference, > > cp_parser_array_notation will update index (which is passed by > > address) and return NULL_TREE, so that it gets back on the normal path. > > > > > One thing I could do is to assume that people won't use array > > > notations in > > braced list. I had it like this a while back but I made the change to > > make sure I have covered more cases. Please let me know if that is OK and I > will fix it. > > > > Yes, that's OK. > > > > > > > I looked into this. But, magic_varargs_p is static to call.c. Should > > > I make it non- > > static? > > > > Yes. > > > > > After making it non-static I was planning to do something like this: > > > > > > if (magic_varargs_p (fndecl) > > > Nargs = (*params)->length (); > > > else > > > nargs = convert_arguments (...) > > > > > > Is that OK with you? > > > > I was thinking to check magic_varargs_p in convert_arguments, where it > > currently has > > > > > if (fndecl && DECL_BUILT_IN (fndecl) > > > && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P) > > > /* Don't do ellipsis conversion for __built_in_constant_p > > > as this will result in spurious errors for non-trivial > > > types. */ > > > > change to "if (fndecl && magic_varargs_p (fndecl))" > > > > This change is implemented. > > > >> By the way, why are you breaking out the elements of the > > >> ARRAY_NOTATION_REF into a cilkplus_an_parts rather than using the > > >> _REF directly? > > > > > > I use the different parts of array notations for error checking and > > > to create the > > outer for-loop. Also, to create the ARRAY_REF I need the induction variable. > > > > I understand the need for cilkplus_an_loop_parts, but > > cilkplus_an_parts seems to contain exactly the same information as the > ARRAY_NOTATION_REF. > > > > > Fixed! By the way, what is SFINAE? > > > > SFINAE stands for "substitution failure is not an error". During > > template argument deduction, once we have a full set of template > > arguments we try to substitute them into the template declaration. In > > that context, things that would normally cause an error just fail and return > error_mark_node silently. > > > > > diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index > > > 55ed6a5..9d570b2 100644 Binary files a/gcc/cp/ChangeLog and > > > b/gcc/cp/ChangeLog differ > > > > This patch still has ChangeLog entries. > > > > This time, I ran the command you gave me. Please tell me how it looks. > > > > + new_var = get_temp_regvar (TREE_TYPE (retval_expr), > > > + build_zero_cst (TREE_TYPE (retval_expr))); > > > new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR, > > > + TREE_OPERAND (retval_expr, 1), > > > + tf_warning_or_error); > > > > Why not pass TREE_OPERAND (retval_expr, 1) as the init to get_temp_regvar? > > > > > new_var = TREE_OPERAND (retval_expr, 1) > > and if TREE_OPERAND (retval_expr, 1) has array notations then it wont get > expanded correctly. > > Another solution is to replace get_tmp_regvar with get_temporary_var () + > add_decl_expr (..). I have implemented this because it looks "more correct" > > > > > - 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); > > > > > > @@ -6180,7 +6158,6 @@ cp_parser_array_notation (location_t loc, > > cp_parser *parser, tree init_index, > > > 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; > > > > This change looks like now you will only restore > > parser->colon_corrects_to_scope_p if you have a stride. I would > > parser->suggest > > putting back the first restore, and removing all the > > corrects_to_scope_p code from the stride block, since there can't be > > an array-notation colon after the stride. > > I am setting the scope correction to false right before I look for length and > restore it right after I parse the scope (i.e. outside the if-statement). I think this > should fix the issue. > > > > > >>> + /* 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)) > > >> > > >> This seems impossible, since 'var' is created to have the same type as 'start'. > > > > > > As you suggested further in the email, I have made var of type > > > ptrdiff_type, so > > I think I should keep this. > > > > I think it would be better to convert start/stride to ptrdiff_t. > > > > I don't think I can do that. Stride can be negative and if I am not mistaken, > ptrdiff_t is unsigned. > > > Incidentally, types should be compared with same_type_p rather than ==. > > > > > + 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; > > > + } > > > + } > > > > Another place that should use tree_int_cst_equal. > > > > Fixed! > > > > + /* No need to compare ii < rhs_rank && ii >= lhs_rank because valid > Array > > > + notation expression cannot RHS's rank cannot be greater > > > + than LHS. */ > > > > Too many "cannot"s. > > > Sorry. Fixed. > > > > + if (processing_template_decl) > > > + { > > > + array_type = TREE_TYPE (array_value); > > > + type = TREE_TYPE (array_type); > > > + } > > > > We should be able to parse array notation in a template even when the > > array expression has unknown type. In a template, just parse and > > remember the raw expressions without worrying about diagnostics and > conversions. > > > > > + 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; > > > + } > > > + } > > ... > > Fixed! > > > > + /* If an array's index is an array notation, then its rank cannot be > > > + greater than one. */ > > > + if (flag_enable_cilkplus && contains_array_notation_expr (idx)) > > > + { > > > + size_t rank = 0; > > > + > > > + /* If find_rank returns false, then it should have reported an error, > > > + thus it is unnecessary for repetition. */ > > > + if (!find_rank (loc, idx, idx, true, &rank)) > > > + return error_mark_node; > > > + if (rank > 1) > > > + { > > > + error_at (loc, "rank of the array%'s index is greater than 1"); > > > + return error_mark_node; > > > + } > > > + } > > This one error is much easier to do it here than anywhere else. An array_ref > could be a parameter inside a function, part of a modify expression, unary > expression etc. If I move it to transformation stage, I have to do checks in all > these places and there is a small chance some will slip through the cracks. This is > almost a fool proof way of doing it. Such things have been done before. For > example, Open MP does a return expression check in finish_return_stmt (even > though this is a different issue we are talking about). > > If it is the code lines that is an issue, then I am willing to enclose that in a > function or #define. > > > > > + if (flag_enable_cilkplus && contains_array_notation_expr (op0)) > > > + type0 = find_correct_array_notation_type (op0); else > > > + type0 = TREE_TYPE (op0); > > ... > > Fixed! > > > > + 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; > > > + } > > Fixed! > > > ... > > > + /* 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; > > > > More changes that should be unnecessary since ARRAY_NOTATION_REF has a > > normal type. > > > > Fixed! > > > What remaining obstacles are there to sharing most of the expansion > > code between C and C++? That can be a separate patch, of course. > > > > Jason gcc/ChangeLog 2013-06-25 Balaji V. Iyer * builtins.def: Fixed the function type of CILKPLUS_BUILTIN. gcc/c/ChangeLog 2013-06-25 Balaji V. Iyer * c-parser.c (c_parser_array_notation): Removed rejection of array notations in an array of function pointers. gcc/c-family/ChangeLog 2013-06-25 Balaji V. Iyer * 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-25 Balaji V. Iyer * parser.c (cp_parser_array_notation): Removed rejection array notation of type function pointers. Used cp_fold_convert instead of fold_build1. Moved variable that saves colon corrects variable into the if-statement. (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 (cp_length_mismatch_in_expr_p): Combined two if statements into one and compared integers using tree_int_cst_equal. (make_triplet_val_inv): Removed loc and cry parameters. Also, replaced build_decls with get_temp_regvar. (replace_invariant_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 checking to using tree_int_cst_equal. (expand_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. * 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-25 Balaji V. Iyer * 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. diff --git a/gcc/builtins.def b/gcc/builtins.def index 91879a6..9b55b1f 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -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 diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c index 0e2a431..ae96941 100644 --- a/gcc/c-family/array-notation-common.c +++ b/gcc/c-family/array-notation-common.c @@ -86,7 +86,6 @@ length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y) { size_t ii, jj; tree start = NULL_TREE; - HOST_WIDE_INT l_start, l_node; for (jj = 0; jj < y; jj++) { start = NULL_TREE; @@ -99,15 +98,11 @@ length_mismatch_in_expr_p (location_t loc, tree **list, size_t x, size_t y) /* If start 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]) == INTEGER_CST) - { - l_node = int_cst_value (list[ii][jj]); - l_start = int_cst_value (start); - if (absu_hwi (l_start) != absu_hwi (l_node)) - { - error_at (loc, "length mismatch in expression"); - return true; - } + if (TREE_CODE (list[ii][jj]) == INTEGER_CST + && !tree_int_cst_equal (list[ii][jj], start)) + { + error_at (loc, "length mismatch in expression"); + return true; } } else @@ -269,6 +264,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)) @@ -356,6 +353,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); } @@ -431,6 +431,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) { @@ -573,53 +576,49 @@ cilkplus_extract_an_triplets (vec *list, size_t size, size_t rank, vec > *node) { vec > 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++) + + if (rank > 0) + for (size_t ii = 0; ii < size; ii++) { - (*node)[ii].safe_push (init); - array_exprs[ii].safe_push (NULL_TREE); + (*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 @@ -635,16 +634,15 @@ fix_sec_implicit_args (location_t loc, vec *list, vec *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 " diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index d6a500e..c7846ce 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -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) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6817bfc..425ef9b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -216,7 +216,6 @@ static void add_candidates (tree, tree, const vec *, 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 diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c index 92272b3..a24e672 100644 --- a/gcc/cp/cp-array-notation.c +++ b/gcc/cp/cp-array-notation.c @@ -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. */ @@ -79,7 +78,7 @@ create_an_loop (tree init, tree cond, tree incr, tree body) } /* Returns true if there is a length mismatch among exprssions that are at the - same dimension and one the same side of the equal sign. The Array notation + same dimension and on the same side of the equal sign. The Array notation lengths (LIST->LENGTH) is passed in as a 2D vector of trees. */ static bool @@ -87,14 +86,13 @@ cp_length_mismatch_in_expr_p (location_t loc, vec >list) { size_t ii, jj; tree length = NULL_TREE; - HOST_WIDE_INT l_length, l_node; size_t x = list.length (); - size_t y = list[0].length (); - + size_t y = list[0].length (); + for (jj = 0; jj < y; jj++) { - length = NULL_TREE; + length = NULL_TREE; for (ii = 0; ii < x; ii++) { if (!length) @@ -104,20 +102,16 @@ cp_length_mismatch_in_expr_p (location_t loc, vec >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 - /* We set the length node as the current node just in case it turns - out to be an integer. */ + /* We set the list[ii][jj].length as the current node just in case + it turns out to be an integer. */ length = list[ii][jj].length; } } @@ -128,17 +122,12 @@ cp_length_mismatch_in_expr_p (location_t loc, vec >list) 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 (integer_type_node, *value); } /* Returns a vector of size RANK that contains an ARRAY_REF. This vector is @@ -238,7 +227,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; @@ -250,17 +239,8 @@ 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); + { + 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); @@ -281,7 +261,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 *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 (); @@ -351,7 +330,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: @@ -380,24 +359,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); @@ -406,26 +391,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) @@ -440,35 +408,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; @@ -479,9 +448,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: @@ -516,8 +487,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, @@ -567,21 +536,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++) @@ -591,7 +547,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 (); @@ -680,10 +636,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 @@ -705,8 +658,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; } @@ -721,17 +672,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); @@ -751,31 +702,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, @@ -789,24 +738,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) @@ -855,12 +795,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++) { @@ -870,17 +810,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); @@ -913,7 +849,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 > an_info = vNULL; vec an_loop_info = vNULL; @@ -930,13 +865,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"); @@ -957,13 +896,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"); @@ -995,11 +938,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)) @@ -1023,37 +966,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++) @@ -1063,7 +997,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 (); @@ -1108,14 +1042,14 @@ expand_unary_array_notation_exprs (tree orig_stmt) { vec *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; @@ -1135,22 +1069,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, @@ -1159,7 +1090,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++) @@ -1169,7 +1100,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 (); @@ -1185,21 +1116,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; } @@ -1336,19 +1281,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; @@ -1368,44 +1315,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) @@ -1508,20 +1450,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)) diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 38ef878..590d857 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -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)); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 00ee450..a3438a8 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f3bc27a..820a89a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6062,10 +6062,10 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* 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 + INIT_INDEX is NULL, then we have special case where 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. */ + 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, @@ -6074,26 +6074,22 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, 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; if (!array_value || array_value == error_mark_node) { cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - - if (processing_template_decl) - { - array_type = TREE_TYPE (array_value); - type = TREE_TYPE (array_type); - } + + array_type = TREE_TYPE (array_value); + if (processing_template_decl) + type = TREE_TYPE (array_type); else { - array_type = TREE_TYPE (array_value); gcc_assert (array_type); type = array_type; } + token = cp_lexer_peek_token (parser->lexer); if (!token) { @@ -6117,44 +6113,24 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, || TREE_CODE (array_type) == POINTER_TYPE) { error_at (loc, "start-index and length fields necessary for " - "using array notations in pointers or records"); + "using array notation 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"); + "using array notation with array of unknown bound"); 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); + start_index = cp_fold_convert (ptrdiff_type_node, start_index); + length_index = size_binop + (PLUS_EXPR, TYPE_MAXVAL (array_type_domain), size_one_node); + length_index = cp_fold_convert (ptrdiff_type_node, length_index); + stride = build_int_cst (ptrdiff_type_node, 1); } else if (init_index != error_mark_node) { @@ -6165,25 +6141,19 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, start_index = init_index; cp_lexer_consume_token (parser->lexer); - saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; + bool 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); @@ -6193,7 +6163,9 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, } } else - stride = build_one_cst (integer_type_node); + stride = build_one_cst (integer_type_node); + /* Disable correcting single colon correcting to scope. */ + parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; } else { @@ -6211,13 +6183,7 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index, 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); @@ -6248,8 +6214,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, if (flag_enable_cilkplus && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON) /* If we are here, then we have something like this: - ARRAY[:] - */ + ARRAY[:] */ postfix_expression = cp_parser_array_notation (loc, parser, NULL_TREE, postfix_expression); else @@ -6259,8 +6224,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, 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. - */ + 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 @@ -6288,7 +6252,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, { error_at (cp_lexer_peek_token (parser->lexer)->location, "braced list index is not allowed with array " - "notations"); + "notation"); index = error_mark_node; } } @@ -9550,9 +9514,6 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr, finish_compound_stmt (compound_stmt); /* 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; } @@ -9745,14 +9706,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; @@ -10310,12 +10263,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; @@ -10342,15 +10289,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; @@ -10367,19 +10305,10 @@ cp_parser_iteration_statement (cp_parser* parser) /* Parse the body of the for-statement. */ parser->in_statement = IN_ITERATION_STMT; cp_parser_already_scoped_statement (parser); - parser->in_statement = in_statement; + 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; @@ -16953,54 +16882,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,10 +18277,6 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser, 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); @@ -22355,12 +22256,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)); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 667e37f..5dafdcd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15739,9 +15739,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; @@ -19143,11 +19140,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); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0a460a4..87c1560 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5b321ce..fb9a537 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3493,10 +3493,6 @@ cp_build_function_call_vec (tree function, vec **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 **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. */ @@ -3954,17 +3949,10 @@ cp_build_binary_op (location_t location, TREE_TYPE (t)); op1 = t; } - } - - 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. */ @@ -5167,13 +5155,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))) { @@ -7852,13 +7833,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); diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c index 68c8859..4b54f4d 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c @@ -1,3 +1,4 @@ +/* { dg-do compile { target c } } */ /* { dg-options "-fcilkplus" } */ int main(void) diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c index 69aaa52..690e89a 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c @@ -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" } } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c index 024a158..fa6d900 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c @@ -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; } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c index 14421d9..814786b 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c @@ -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; diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c index b5e37ce..eb3c1f1 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c @@ -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" } */