From patchwork Mon Mar 25 21:39:35 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: 230989 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 027F92C0091 for ; Tue, 26 Mar 2013 08:40:11 +1100 (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:in-reply-to :content-type:mime-version; q=dns; s=default; b=TqYqKLMB9olGvRxi h+v0UUjWd2JN2El5Lwp+Q0RUBaqK3BI/Kst7goU7IJCvX2rTHtlI7s1fClAdslKp 2dt9cl4AetC4Ks42Eq+7R03JRgAkk4uqUBQQRLdAHOYLoEyjCE6aGjXd6x9+LnCq ZvyDe7yDYN6Uwmr7QifxUMp/5vQ= 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:in-reply-to :content-type:mime-version; s=default; bh=+WUUz8UDjlzlo74FJtsZZ3 crn2k=; b=hb0WBmdn1BFPf3+SBCDA+oCyYkHU6XERR74wU6UcwGxxQ6JExEayCY 48oBfFRgOMIbZdjoQP/1QjTL8iRpea0Cna+YvToEEWagqjt8rDP8VDDkqX0QJ7v+ 5Q8pbR82/X5nYq5wm5TioJeIhXjLuBAbRxM7mwFjmAi5NcM5D1rEw= Received: (qmail 6911 invoked by alias); 25 Mar 2013 21:39:56 -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 6874 invoked by uid 89); 25 Mar 2013 21:39:40 -0000 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; Mon, 25 Mar 2013 21:39:40 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 25 Mar 2013 14:38:00 -0700 X-ExtLoop1: 1 Received: from fmsmsx108.amr.corp.intel.com ([10.19.9.228]) by orsmga001.jf.intel.com with ESMTP; 25 Mar 2013 14:39:36 -0700 Received: from fmsmsx102.amr.corp.intel.com ([169.254.2.241]) by FMSMSX108.amr.corp.intel.com ([169.254.10.167]) with mapi id 14.01.0355.002; Mon, 25 Mar 2013 14:39:36 -0700 From: "Iyer, Balaji V" To: Aldy Hernandez CC: "gcc-patches@gcc.gnu.org" , "Joseph Myers [joseph@codesourcery.com]" Subject: RE: [patch] cilkplus array notation for C (clean, independent patchset, take 1) Date: Mon, 25 Mar 2013 21:39:35 +0000 Message-ID: References: <5149D62F.9070503@redhat.com> , <51507F31.1080003@redhat.com> In-Reply-To: <51507F31.1080003@redhat.com> MIME-Version: 1.0 X-Virus-Found: No Hello Joseph, Aldy et al., Attached, please find a fixed patch. This patch should fix all the issues that Joseph mentioned in both the emails with the exception of the built-in __sec_reduce functions. Aldy is currently looking into those. The changes that Aldy mentioned below have also been fixed with the appropriate comments below: My current email client is not putting the '>' correctly, so all my comments are in CAPS below. I am currently looking into fixing that. Till then, I am sorry for the inconvenience. Thanks, Balaji V. Iyer. diff --git gcc/c-family/ChangeLog.cilkplus gcc/c-family/ChangeLog.cilkplus index 6591fd1..eb7ff47 100644 --- gcc/c-family/ChangeLog.cilkplus +++ gcc/c-family/ChangeLog.cilkplus @@ -1,7 +1,7 @@ 2013-03-20 Balaji V. Iyer * c-common.c (c_define_builtins): When cilkplus is enabled, the - function array_notation_init_builtins() is called. + function array_notation_init_builtins is called. (c_common_init_ts): Added ARRAY_NOTATION_REF as typed. * c-common.def (ARRAY_NOTATION_REF): New tree. * c-common.h (build_array_notation_expr): New function declaration. @@ -18,5 +18,6 @@ (array_notation_reduce_type): New enumerator. * c-pretty-print.c (pp_c_postifix_expression): Added a new case for ARRAY_NOTATION_REF. + (pp_c_expression): Likewise. * c.opt (flag_enable_cilkplus): New flag. * array-notation-common.c: New file. diff --git gcc/c-family/array-notation-common.c gcc/c-family/array-notation-common.c index 7089c8e..b775225 100644 --- gcc/c-family/array-notation-common.c +++ gcc/c-family/array-notation-common.c @@ -29,19 +29,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-iterator.h" #include "diagnostic-core.h" -int extract_sec_implicit_index_arg (location_t, tree); -bool is_sec_implicit_index_fn (tree); -void array_notation_init_builtins (void); - -/* Mark the FNDECL as cold, meaning that the function specified by FNDECL is - not run as is. */ - -static void -mark_cold (tree fndecl) -{ - DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("cold"), NULL_TREE, - DECL_ATTRIBUTES (fndecl)); -} /* This function inititializes array notation specific builtin information. */ @@ -54,67 +41,56 @@ array_notation_init_builtins (void) func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_add", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_mul", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_all_zero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_any_zero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_max", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_min", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_min_ind", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_max_ind", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_any_nonzero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_reduce_all_nonzero", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, integer_type_node, NULL_TREE); new_func = build_fn_decl ("__sec_implicit_index", func_type); - mark_cold (new_func); new_func = lang_hooks.decls.pushdecl (new_func); func_type = build_function_type_list (integer_type_node, ptr_type_node, @@ -167,25 +143,23 @@ is_sec_implicit_index_fn (tree func_name) sec_implicit_index function. FN's location in the source file is is indicated by LOCATION. */ -int +HOST_WIDE_INT extract_sec_implicit_index_arg (location_t location, tree fn) { tree fn_arg; HOST_WIDE_INT return_int = 0; - if (!fn) - return -1; if (TREE_CODE (fn) == CALL_EXPR) { fn_arg = CALL_EXPR_ARG (fn, 0); if (really_constant_p (fn_arg)) - return_int = (int) int_cst_value (fn_arg); + return_int = int_cst_value (fn_arg); else { if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (fn)) location = EXPR_LOCATION (fn); error_at (location, "__sec_implicit_index parameter must be a " - "constant integer expression"); + "integer constant expression"); return -1; } } diff --git gcc/c-family/c-common.h gcc/c-family/c-common.h index edcff2e..001e0c4 100644 --- gcc/c-family/c-common.h +++ gcc/c-family/c-common.h @@ -541,7 +541,7 @@ extern tree build_modify_expr (location_t, tree, tree, enum tree_code, extern tree build_array_notation_expr (location_t, tree, tree, enum tree_code, location_t, tree, tree); extern tree build_array_notation_ref (location_t, tree, tree, tree, tree, tree); -extern void find_rank (tree, bool, size_t *); +extern bool find_rank (location_t, tree, tree, bool, size_t *); extern tree build_indirect_ref (location_t, tree, ref_operator); extern int field_decl_cmp (const void *, const void *); @@ -1173,5 +1173,10 @@ typedef enum array_notation_reduce_type { extern int extract_sec_implicit_index_arg (location_t, tree); extern bool is_sec_implicit_index_fn (tree); extern void array_notation_init_builtins (void); - +extern struct c_expr fix_array_notation_expr (location_t, enum tree_code, + struct c_expr); +extern bool contains_array_notation_expr (tree); +extern tree expand_array_notation_exprs (tree); +extern tree fix_conditional_array_notations (tree); +extern tree find_correct_array_notation_type (tree); #endif /* ! GCC_C_COMMON_H */ diff --git gcc/c-family/c-pretty-print.c gcc/c-family/c-pretty-print.c index 30c8e80..b8af90c 100644 --- gcc/c-family/c-pretty-print.c +++ gcc/c-family/c-pretty-print.c @@ -1479,11 +1479,11 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) case ARRAY_NOTATION_REF: pp_postfix_expression (pp, ARRAY_NOTATION_ARRAY (e)); pp_c_left_bracket (pp); - pp_postfix_expression (pp, ARRAY_NOTATION_START (e)); + pp_expression (pp, ARRAY_NOTATION_START (e)); pp_colon (pp); - pp_postfix_expression (pp, ARRAY_NOTATION_LENGTH (e)); + pp_expression (pp, ARRAY_NOTATION_LENGTH (e)); pp_colon (pp); - pp_postfix_expression (pp, ARRAY_NOTATION_STRIDE (e)); + pp_expression (pp, ARRAY_NOTATION_STRIDE (e)); pp_c_right_bracket (pp); break; @@ -2161,6 +2161,7 @@ pp_c_expression (c_pretty_printer *pp, tree e) case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: case ARRAY_REF: + case ARRAY_NOTATION_REF: case CALL_EXPR: case COMPONENT_REF: case BIT_FIELD_REF: diff --git gcc/c/c-array-notation.c gcc/c/c-array-notation.c index 38ed7ea..9ee281e 100755 --- gcc/c/c-array-notation.c +++ gcc/c/c-array-notation.c @@ -31,19 +31,17 @@ #include "gcc.h" #include "c-family/c-common.h" -void replace_array_notations (tree *, bool, vec *, +static void replace_array_notations (tree *, bool, vec *, vec *); -void find_rank (tree, bool, size_t *); -void extract_array_notation_exprs (tree, bool, vec **); -tree fix_conditional_array_notations (tree); -struct c_expr fix_array_notation_expr (location_t, enum tree_code, - struct c_expr); -bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type); +static void extract_array_notation_exprs (tree, bool, vec **); +static bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type); static tree fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var); -bool contains_array_notation_expr (tree expr); -tree expand_array_notation_exprs (tree t); +/* This structure holds all the scalar values and its appropriate variable + replacment. It is mainly used by the function that pulls all the invariant + parts that should be executed only once, which comes with array notation + expressions. */ struct inv_list { vec *list_values; @@ -51,72 +49,84 @@ struct inv_list }; -/* Returns the rank of ARRAY through the *RANK. The user can specify whether - (s)he wants to step into array_notation-specific builtin functions - (specified by the IGNORE_BUILTIN_FN). +/* Set *RANK of expression ARRAY, ignoring array notation specific built-in + functions if IGNORE_BUILTIN_FN is true. The ORIG_EXPR is printed out if an + error occured in the rank calculation. The functions returns false if it + encounters an error in rank calculation. If ARRAY can be NULL, since it is + recursively accessing all the fields in a subtree. If so, then just return + true. For example, an array notation of A[:][:] or B[0:10][0:5:2] or C[5][:][1:0] all have a rank of 2. */ -void -find_rank (tree array, bool ignore_builtin_fn, size_t *rank) +bool +find_rank (location_t loc, tree orig_expr, tree array, bool ignore_builtin_fn, + size_t *rank) { tree ii_tree; - size_t current_rank = 0, ii = 0; + size_t ii = 0, current_rank = 0; an_reduce_type dummy_type = REDUCE_UNKNOWN; + if (!array) - return; + return true; else if (TREE_CODE (array) == ARRAY_NOTATION_REF) { for (ii_tree = array; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF; ii_tree = ARRAY_NOTATION_ARRAY (ii_tree)) current_rank++; - if (*rank == 0) - *rank = current_rank; + if (*rank == 0) + *rank = current_rank; + else if (*rank != current_rank) + { + error_at (loc, "rank mismatch in expression %qE", orig_expr); + return false; + } } else if (TREE_CODE (array) == STATEMENT_LIST) { tree_stmt_iterator ii_tsi; for (ii_tsi = tsi_start (array); !tsi_end_p (ii_tsi); tsi_next (&ii_tsi)) - find_rank (*tsi_stmt_ptr (ii_tsi), ignore_builtin_fn, rank); + if (!find_rank (loc, orig_expr, *tsi_stmt_ptr (ii_tsi), + ignore_builtin_fn, rank)) + return false; } else { if (TREE_CODE (array) == CALL_EXPR) { tree func_name = CALL_EXPR_FN (array); + tree arg; + call_expr_arg_iterator iter; if (TREE_CODE (func_name) == ADDR_EXPR) if (!ignore_builtin_fn) if (is_builtin_array_notation_fn (func_name, &dummy_type)) - /* If it is a builtin function, then we know it returns a - scalar. */ - return; - if (TREE_CODE (TREE_OPERAND (array, 0)) == INTEGER_CST) - { - int length = TREE_INT_CST_LOW (TREE_OPERAND (array, 0)); - for (ii = 0; ii < (size_t) length; ii++) - find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank); - } - else - gcc_unreachable (); + /* If it is a builtin function, then it returns a scalar. */ + return true; + + FOR_EACH_CALL_EXPR_ARG (arg, iter, array) + if (!find_rank (loc, orig_expr, arg, ignore_builtin_fn, rank)) + return false; } else for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (array)); ii++) - find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank); + if (!find_rank (loc, orig_expr, TREE_OPERAND (array, ii), + ignore_builtin_fn, rank)) + return false; } - return; + return true; } -/* Extracts all the array notations specified in NODE and stores them in a - dynamic tree array of ARRAY_LIST whose size is stored in *LIST_SIZE. The - user can specify if (s)he wants to ignore the array notations inside the - array-notation specific builtin functions (by setting IGNORE_BUILTIN_FN to - true). */ +/* Extracts all array notations in NODE and stores them in ARRAY_LIST. If + IGNORE_BUILTIN_FN is set, then array notations inside array notation + specific builtin functions are ignored. The NODE can be anything from a + full function to a single variable. Since function is stepping through all + the subtrees, there is a good chance that node can be a NULL_TREE. If so, + then the function just returns. */ -void +static void extract_array_notation_exprs (tree node, bool ignore_builtin_fn, vec **array_list) { @@ -148,6 +158,8 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, } else if (TREE_CODE (node) == CALL_EXPR) { + tree arg; + call_expr_arg_iterator iter; if (is_builtin_array_notation_fn (CALL_EXPR_FN (node), &dummy_type)) { if (ignore_builtin_fn) @@ -163,17 +175,9 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, vec_safe_push (*array_list, node); return; } - if (TREE_CODE (TREE_OPERAND (node, 0)) == INTEGER_CST) - { - int length = TREE_INT_CST_LOW (TREE_OPERAND (node, 0)); - for (ii = 0; ii < (size_t) length; ii++) - extract_array_notation_exprs - (TREE_OPERAND (node, ii), ignore_builtin_fn, array_list); - } - else - gcc_unreachable (); /* We should not get here. */ - + FOR_EACH_CALL_EXPR_ARG (arg, iter, node) + extract_array_notation_exprs (arg, ignore_builtin_fn, array_list); } else for (ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (node)); ii++) @@ -183,15 +187,15 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn, } -/* Replaces all occurances of array notations in tree ORIG that matches the - ones in LIST with the one in ARRAY_OPERAND. The size of list and - ARRAY_OPERAND is ARRAY_SIZE. For example, ARRAY_OPERAND[x] for some index - 'x' will have the equivalent ARRAY_REF for the ARRAY_NOTATION_REF specified - in LIST[x]. The user can specify if (s)he wants to ignore the array - notations inside the array-notation specific builtin functions (using the - bool variable IGNORE_BUILTIN_FN). */ +/* Replaces all the occurances of array notations in *LIST with the appropriate + one in ARRAY_OPERAND. If IGNORE_BUILTIN_FN is set, then array notations + inside array-notation specific builtin functions are ignored. ORIG can be + anything from a collection of statement lists to a single variable. Since + this function steps through all the subtrees, it is probable that *ORIG can + be a NULL_TREE. If so, then the function just returns. +*/ -void +static void replace_array_notations (tree *orig, bool ignore_builtin_fn, vec *list, vec *array_operand) @@ -221,6 +225,8 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, } else if (TREE_CODE (*orig) == CALL_EXPR) { + tree arg; + call_expr_arg_iterator iter; if (is_builtin_array_notation_fn (CALL_EXPR_FN (*orig), &dummy_type)) { if (!ignore_builtin_fn) @@ -244,16 +250,14 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, } return; } - if (TREE_CODE (TREE_OPERAND (*orig, 0)) == INTEGER_CST) + ii = 0; + FOR_EACH_CALL_EXPR_ARG (arg, iter, *orig) { - int length = TREE_INT_CST_LOW (TREE_OPERAND (*orig, 0)); - for (ii = 0; ii < (size_t) length; ii++) - replace_array_notations - (&TREE_OPERAND (*orig, ii), ignore_builtin_fn, list, - array_operand); - } - else - gcc_unreachable (); /* We should not get here! */ + replace_array_notations (&arg, ignore_builtin_fn, list, + array_operand); + CALL_EXPR_ARG (*orig, ii) = arg; + ii++; + } } else { @@ -264,9 +268,11 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn, return; } -/* This function will find all the scalar expressions in *TP and push it in - DATA struct, typecasted to (void *). If *WALK_SUBTREES is set to 0 then - we have do not go into the *TP's subtrees. */ +/* Find all the scalar expressions in *TP and push them in DATA struct, + typecasted to (void *). If *WALK_SUBTREES is set to 0 then do not go into + the *TP's subtrees. Since this function steps through all the subtrees, *TP + and TP can be both NULL_TREE and NULL respectively. If so, then the function + just returns NULL_TREE. */ static tree find_inv_trees (tree *tp, int *walk_subtrees, void *data) @@ -322,7 +328,11 @@ replace_inv_trees (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } -/* Replaces all the scalar expressions in *NODE. */ +/* Replaces all the scalar expressions in *NODE. Returns a STATEMENT_LIST that + holds the NODE along with variables that holds the results of the invariant + expressions. Since this function steps through all the subtrees, it is + probable than *NODE or NODE can be NULL_TREE and NULL respectively. If so, + then the function just returns NULL_TREE. */ tree replace_invariant_exprs (tree *node) @@ -331,6 +341,7 @@ replace_invariant_exprs (tree *node) tree node_list = NULL_TREE; tree t = NULL_TREE, new_var = NULL_TREE, new_node; struct inv_list data; + if (!node || !*node) return NULL_TREE; @@ -398,7 +409,9 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, already. Not necessary to send out multiple error messages. */ if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; - find_rank (rhs, false, &rhs_rank); + + if (!find_rank (location, rhs, rhs, false, &rhs_rank)) + return error_mark_node; extract_array_notation_exprs (rhs, false, &rhs_list); rhs_list_size = vec_safe_length (rhs_list); @@ -435,8 +448,11 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, lhs_rank = 0; rhs_rank = 0; - find_rank (lhs, true, &lhs_rank); - find_rank (rhs, true, &rhs_rank); + if (!find_rank (location, lhs, lhs, true, &lhs_rank)) + return error_mark_node; + + if (!find_rank (location, rhs, rhs, true, &rhs_rank)) + return error_mark_node; if (lhs_rank == 0 && rhs_rank == 0) { @@ -467,12 +483,22 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, if (lhs_rank == 0 && rhs_rank != 0 && TREE_CODE (rhs) != CALL_EXPR) { tree rhs_base = rhs; - for (ii = 0; ii < (size_t) rhs_rank; ii++) - rhs_base = ARRAY_NOTATION_ARRAY (rhs); + if (TREE_CODE (rhs_base) == ARRAY_NOTATION_REF) + { + for (ii = 0; ii < (size_t) rhs_rank; ii++) + rhs_base = ARRAY_NOTATION_ARRAY (rhs); - error_at (location, "%qD cannot be scalar when %qD is not", lhs, - rhs_base); - return error_mark_node; + error_at (location, "%qE cannot be scalar when %qE is not", lhs, + rhs_base); + return error_mark_node; + } + else + { + error_at (location, "%qE cannot be scalar when %qE is not", lhs, + rhs_base); + return error_mark_node; + } + } if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank) { @@ -745,8 +771,6 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, rhs_vector[ii][jj] = false; } - - for (ii = 0; ii < lhs_rank; ii++) { if (lhs_vector[0][ii]) @@ -758,7 +782,6 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, NOP_EXPR, location, build_zero_cst (TREE_TYPE (lhs_var[ii])), TREE_TYPE (lhs_var[ii])); - } } @@ -1032,19 +1055,19 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, } /* The following statements will do the following: - * : (in order from outermost to innermost) - * if (cond_expr) then go to body_label - * else go to exit_label - * : - * array expression - * - * (the increment, goto and exit_label goes from innermost to - * outermost). - * ii++ and jj++ - * go to if_stmt_label - * : - * - */ + : (in order from outermost to innermost) + if (cond_expr) then go to body_label + else go to exit_label + : + array expression + + (the increment, goto and exit_label goes from innermost to + outermost). + ii++ and jj++ + go to if_stmt_label + : + + */ for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++) @@ -1079,7 +1102,9 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, /* Encloses the conditional statement passed in STMT with a loop around it and replaces the condition in STMT with a ARRAY_REF tree-node to the array. - The condition must have a ARRAY_NOTATION_REF tree. */ + The condition must have a ARRAY_NOTATION_REF tree. An expansion of array + notation in STMT is returned in a STATEMENT_LIST. */ + static tree fix_conditional_array_notations_1 (tree stmt) @@ -1105,7 +1130,11 @@ fix_conditional_array_notations_1 (tree stmt) /* Otherwise dont even touch the statement. */ return stmt; - find_rank (cond, false, &rank); + location = EXPR_LOCATION (stmt); + + if (!find_rank (location, cond, cond, false, &rank)) + return error_mark_node; + extract_array_notation_exprs (cond, false, &array_list); loop = push_stmt_list (); for (ii = 0; ii < vec_safe_length (array_list); ii++) @@ -1130,7 +1159,9 @@ fix_conditional_array_notations_1 (tree stmt) } } } - find_rank (cond, true, &rank); + + if (!find_rank (location, cond, cond, true, &rank)) + return error_mark_node; if (rank == 0) { add_stmt (stmt); @@ -1144,7 +1175,6 @@ fix_conditional_array_notations_1 (tree stmt) return stmt; list_size = vec_safe_length (array_list); - location = EXPR_LOCATION (stmt); array_ops = XNEWVEC (tree *, list_size); for (ii = 0; ii < list_size; ii++) @@ -1278,7 +1308,6 @@ fix_conditional_array_notations_1 (tree stmt) location, build_int_cst (TREE_TYPE (array_var[ii]), 0), TREE_TYPE (array_var[ii])); - } for (ii = 0; ii < rank ; ii++) @@ -1457,7 +1486,15 @@ fix_array_notation_expr (location_t location, enum tree_code code, tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init; bool **count_down, **array_vector; - find_rank (arg.value, false, &rank); + if (!find_rank (location, arg.value, arg.value, false, &rank)) + { + /* If this function returns a NULL, we convert the tree value in the + structure to error_mark_node and the parser should take care of the + rest. */ + arg.value = error_mark_node; + return arg; + } + if (rank == 0) return arg; @@ -1634,12 +1671,10 @@ fix_array_notation_expr (location_t location, enum tree_code code, replace_array_notations (&arg.value, true, array_list, array_operand); for (ii = 0; ii < rank; ii++) - { - expr_incr[ii] = - build2 (MODIFY_EXPR, void_type_node, array_var[ii], - build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii], - build_int_cst (TREE_TYPE (array_var[ii]), 1))); - } + expr_incr[ii] = + build2 (MODIFY_EXPR, void_type_node, array_var[ii], + build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii], + build_int_cst (TREE_TYPE (array_var[ii]), 1))); for (jj = 0; jj < rank; jj++) { @@ -1656,7 +1691,6 @@ fix_array_notation_expr (location_t location, enum tree_code code, array_var[jj], array_length[0][jj]); } } - for (ii = 0; ii < rank; ii++) { @@ -1772,10 +1806,11 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) || TREE_CODE (func_parm) == EXCESS_PRECISION_EXPR || TREE_CODE (func_parm) == NOP_EXPR) func_parm = TREE_OPERAND (func_parm, 0); - - find_rank (an_builtin_fn, true, &rank); location = EXPR_LOCATION (an_builtin_fn); + + if (!find_rank (location, an_builtin_fn, an_builtin_fn, true, &rank)) + return error_mark_node; if (rank == 0) return an_builtin_fn; @@ -1783,7 +1818,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) && (an_type == REDUCE_MAX_INDEX || an_type == REDUCE_MIN_INDEX)) { error_at (location, "__sec_reduce_min_ind or __sec_reduce_max_ind cannot" - " have arrays with dimension greater than 1."); + " have arrays with dimension greater than 1"); return error_mark_node; } @@ -1815,7 +1850,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) new_var_type = NULL_TREE; break; default: - gcc_unreachable (); /* You should not reach here. */ + gcc_unreachable (); } array_ops = XNEWVEC (tree *, list_size); @@ -1982,12 +2017,11 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) } replace_array_notations (&func_parm, true, array_list, array_operand); for (ii = 0; ii < rank; ii++) - { - expr_incr[ii] = - build2 (MODIFY_EXPR, void_type_node, array_var[ii], - build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii], - build_int_cst (TREE_TYPE (array_var[ii]), 1))); - } + expr_incr[ii] = + build2 (MODIFY_EXPR, void_type_node, array_var[ii], + build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii], + build_int_cst (TREE_TYPE (array_var[ii]), 1))); + for (jj = 0; jj < rank; jj++) { @@ -2321,17 +2355,14 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) return loop; } -/* Returns true of FUNC_NAME is a builtin array notation function. The type of +/* Returns true if FUNC_NAME is a builtin array notation function. The type of function is returned in *TYPE. */ -bool +static bool is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) { const char *function_name = NULL; - if (!func_name) - return false; - if (TREE_CODE (func_name) == IDENTIFIER_NODE) function_name = IDENTIFIER_POINTER (func_name); else if (TREE_CODE (func_name) == ADDR_EXPR) @@ -2413,7 +2444,7 @@ is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) } -/* Returns true of EXPR (and its subtrees) contain ARRAY_NOTATION_EXPR node. */ +/* Returns true if EXPR (and its subtrees) contain ARRAY_NOTATION_EXPR node. */ bool contains_array_notation_expr (tree expr) @@ -2434,9 +2465,8 @@ contains_array_notation_expr (tree expr) return true; } -/* Replaces array notations in void function call arguments in ARG with loop and - tree-node ARRAY_REF and returns that value in a tree node variable called - LOOP. */ +/* Replaces array notations in void function call arguments in ARG and returns + a STATEMENT_LIST. */ static tree fix_array_notation_call_expr (tree arg) @@ -2463,12 +2493,13 @@ fix_array_notation_call_expr (tree arg) return loop; } - find_rank (arg, false, &rank); + if (!find_rank (location, arg, arg, false, &rank)) + return error_mark_node; + if (rank == 0) return arg; extract_array_notation_exprs (arg, true, &array_list); - if (vec_safe_length (array_list) == 0) return arg; @@ -2747,7 +2778,10 @@ fix_array_notation_call_expr (tree arg) /* Walks through tree node T and find all the call-statments that do not return - anything and fix up any array notations they may carry. */ + anything and fix up any array notations they may carry. The return value + is the same type as T but with all array notations replaced with appropriate + STATEMENT_LISTS. Since this function recursively steps through all the + subtrees, t can be a NULL_TREE. If so, then the function just returns. */ tree expand_array_notation_exprs (tree t) @@ -2802,20 +2836,22 @@ build_array_notation_ref (location_t loc, tree array, tree start_index, tree array_ntn_tree = NULL_TREE; size_t stride_rank = 0, length_rank = 0, start_rank = 0; - if (!TREE_TYPE (start_index) || !INTEGRAL_TYPE_P (TREE_TYPE (start_index))) + if (!INTEGRAL_TYPE_P (TREE_TYPE (start_index))) { error_at (loc, - "start-index of array notation triplet is not an integer."); + "start-index of array notation triplet is not an integer"); return error_mark_node; } - if (!TREE_TYPE (length) || !INTEGRAL_TYPE_P (TREE_TYPE (length))) + if (!INTEGRAL_TYPE_P (TREE_TYPE (length))) { - error_at (loc, "length of array notation triplet is not an integer."); + error_at (loc, "length of array notation triplet is not an integer"); return error_mark_node; } - if (stride && (!TREE_TYPE (stride) || !INTEGRAL_TYPE_P (TREE_TYPE (stride)))) + + /* The stride is an optional field. */ + if (stride && !INTEGRAL_TYPE_P (TREE_TYPE (stride))) { - error_at (loc, "stride of array notation triplet is not an integer."); + error_at (loc, "stride of array notation triplet is not an integer"); return error_mark_node; } if (!stride) @@ -2827,24 +2863,27 @@ build_array_notation_ref (location_t loc, tree array, tree start_index, stride = build_int_cst (TREE_TYPE (start_index), 1); } - find_rank (start_index, false, &start_rank); - find_rank (length, false, &length_rank); - find_rank (stride, false, &stride_rank); + if (!find_rank (loc, start_index, start_index, false, &start_rank)) + return error_mark_node; + if (!find_rank (loc, length, length, false, &length_rank)) + return error_mark_node; + if (!find_rank (loc, stride, stride, false, &stride_rank)) + return error_mark_node; if (start_rank != 0) { error_at (loc, "rank of an array notation triplet's start-index is not " - "zero."); + "zero"); return error_mark_node; } if (length_rank != 0) { - error_at (loc, "rank of an array notation triplet's length is not zero."); + error_at (loc, "rank of an array notation triplet's length is not zero"); return error_mark_node; } if (stride_rank != 0) { - error_at (loc, "rank of array notation triplet's stride is not zero."); + error_at (loc, "rank of array notation triplet's stride is not zero"); return error_mark_node; } @@ -2884,4 +2923,3 @@ find_correct_array_notation_type (tree op) } return return_type; } - diff --git gcc/c/c-parser.c gcc/c/c-parser.c index ba0a7f9..f051ab5 100644 --- gcc/c/c-parser.c +++ gcc/c/c-parser.c @@ -56,12 +56,6 @@ along with GCC; see the file COPYING3. If not see #include "plugin.h" -extern bool contains_array_notation_expr (tree); -extern struct c_expr fix_array_notation_expr (location_t, enum tree_code, - struct c_expr); -extern tree fix_conditional_array_notations (tree); -extern tree expand_array_notation_exprs (tree); - /* Initialization routine for this file. */ @@ -3082,7 +3076,7 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present, dimen = error_mark_node; star_seen = false; error_at (c_parser_peek_token (parser)->location, - "array notations cannot be used in declaration."); + "array notations cannot be used in declaration"); c_parser_consume_token (parser); } else if (c_parser_next_token_is (parser, CPP_MULT)) @@ -3111,7 +3105,7 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present, && c_parser_next_token_is (parser, CPP_COLON)) { error_at (c_parser_peek_token (parser)->location, - "array notations cannot be used in declaration."); + "array notations cannot be used in declaration"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return NULL; } @@ -5068,10 +5062,11 @@ c_parser_for_statement (c_parser *parser) if (flag_enable_cilkplus && contains_array_notation_expr (cond)) { error_at (loc, "array notations cannot be used in a " - "condition for a for-loop."); + "condition for a for-loop"); cond = error_mark_node; } - c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); + c_parser_skip_until_found (parser, CPP_SEMICOLON, + "expected %<;%>"); } } /* Parse the increment expression (the third expression in a @@ -11023,9 +11018,8 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, tree start_index = NULL_TREE, end_index = NULL_TREE, stride = NULL_TREE; tree value_tree = NULL_TREE, type = NULL_TREE, array_type = NULL_TREE; tree array_type_domain = NULL_TREE; - double_int x; - if (!array_value || array_value == error_mark_node) + if (array_value == error_mark_node) { /* No need to continue. If either of these 2 were true, then an error must be emitted already. Thus, no need to emit them twice. */ @@ -11038,7 +11032,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, type = TREE_TYPE (array_type); token = c_parser_peek_token (parser); - if (token == NULL) + if (token->type == CPP_EOF) { c_parser_error (parser, "expected %<:%> or numeral"); return value_tree; @@ -11052,14 +11046,14 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (TREE_CODE (array_type) == POINTER_TYPE) { error_at (loc, "start-index and length fields necessary for " - "using array notations in pointers."); + "using array notations in pointers"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } if (TREE_CODE (array_type) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with function " - "type."); + "type"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11074,7 +11068,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with " - "function pointer arrays."); + "function pointer arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; @@ -11086,7 +11080,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (!array_type_domain) { error_at (loc, "start-index and length fields necessary for " - "using array notations in dimensionless arrays."); + "using array notations in dimensionless arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11098,13 +11092,13 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, || !TREE_CONSTANT (TYPE_MAXVAL (array_type_domain))) { error_at (loc, "start-index and length fields necessary for " - "using array notations in variable-length arrays."); + "using array notations in variable-length arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } - x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain)); - x.low++; - end_index = double_int_to_tree (integer_type_node, x); + end_index = TYPE_MAXVAL (array_type_domain); + end_index = fold_build2 (PLUS_EXPR, TREE_TYPE (end_index), + end_index, integer_one_node); end_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, end_index); stride = build_int_cst (integer_type_node, 1); stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride); @@ -11120,7 +11114,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (TREE_CODE (array_type) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with function " - "type."); + "type"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; } @@ -11138,7 +11132,7 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE) { error_at (loc, "array notations cannot be used with " - "function pointer arrays."); + "function pointer arrays"); c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); return error_mark_node; diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 15dc83d..59658b7 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -103,8 +103,6 @@ static void readonly_warning (tree, enum lvalue_use); static int lvalue_or_else (location_t, const_tree, enum lvalue_use); static void record_maybe_used_decl (tree); static int comptypes_internal (const_tree, const_tree, bool *, bool *); -extern bool contains_array_notation_expr (tree); -extern tree find_correct_array_notation_type (tree); /* Return true if EXP is a null pointer constant, false otherwise. */ @@ -2305,14 +2303,15 @@ build_array_ref (location_t loc, tree array, tree index) if (TREE_TYPE (array) == error_mark_node || TREE_TYPE (index) == error_mark_node) return error_mark_node; - + if (flag_enable_cilkplus && contains_array_notation_expr (index)) { size_t rank = 0; - find_rank (index, true, &rank); + if (!find_rank (loc, index, index, true, &rank)) + return error_mark_node; if (rank > 1) { - error_at (loc, "rank of the array's index is greater than 1."); + error_at (loc, "rank of the array's index is greater than 1"); return error_mark_node; } } @@ -5130,6 +5129,7 @@ convert_for_assignment (location_t location, tree type, tree rhs, enum tree_code coder; tree rname = NULL_TREE; bool objc_ok = false; + if (errtype == ic_argpass) { tree selector; @@ -9035,13 +9035,13 @@ c_finish_loop (location_t start_locus, tree cond, tree incr, tree body, if (flag_enable_cilkplus && contains_array_notation_expr (cond)) { error_at (start_locus, "array notation expression cannot be used in a " - "loop's condition"); + "loop%'s condition"); return; } if (flag_enable_cilkplus && contains_array_notation_expr (incr) && 0) { error_at (start_locus, "array notation expression cannot be used in a " - "loop's increment expression."); + "loop's increment expression"); return; } diff --git gcc/doc/extend.texi gcc/doc/extend.texi index 627bf69..b22eb79 100644 --- gcc/doc/extend.texi +++ gcc/doc/extend.texi @@ -82,6 +82,7 @@ extensions, accepted by GCC in C90 mode and in C++. * x86 specific memory model extensions for transactional memory:: x86 memory models. * Object Size Checking:: Built-in functions for limited buffer overflow checking. +* Cilk Plus Builtins:: Built-in functions for the Cilk Plus language extension. * Other Builtins:: Other built-in functions. * Target Builtins:: Built-in functions specific to particular targets. * Target Format Checks:: Format checks specific to particular targets. @@ -8762,6 +8763,31 @@ Similar to @code{__builtin_bswap32}, except the argument and return types are 64 bit. @end deftypefn +@node Cilk Plus Builtins +@section Cilk Plus C/C++ language extension Built-in Functions. + +GCC provides support for the following built-in reduction funtions if Cilk Plus +is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag. + +@itemize @bullet +@item __sec_reduce +@item __sec_reduce_add +@item __sec_reduce_all_nonzero +@item __sec_reduce_all_zero +@item __sec_reduce_any_nonzero +@item __sec_reduce_any_zero +@item __sec_reduce_max +@item __sec_reduce_min +@item __sec_reduce_max_ind +@item __sec_reduce_min_ind +@item __sec_reduce_mul +@item __sec_reduce_mutating +@end itemize + +Further details and examples about these built-in functions are described +in the Cilk Plus language manual which can be found at +@uref{http://www.cilkplus.org}. + @node Target Builtins @section Built-in Functions Specific to Particular Target Machines diff --git gcc/doc/passes.texi gcc/doc/passes.texi index 81b6502..045f964 100644 --- gcc/doc/passes.texi +++ gcc/doc/passes.texi @@ -125,25 +125,7 @@ inside conditions, they are transformed using the function @code{fix_conditional_array_notations}. The C language-specific routines are located in @file{c/c-array-notation.c} and the equivalent C++ routines are in file @file{cp/cp-array-notation.c}. Common routines such as functions to -initialize builtin functions are stored in @file{array-notation-common.c}. In -the current array notation implementation there are 12 builtin reduction -operations. Details about these functions and their usage are available in -the Cilk Plus language specification at @w{@uref{http://www.cilkplus.org}}. - -@itemize @bullet -@item __sec_reduce_add -@item __sec_reduce_mul -@item __sec_reduce_max -@item __sec_reduce_min -@item __sec_reduce_max_ind -@item __sec_reduce_min_ind -@item __sec_reduce_all_zero -@item __sec_reduce_all_nonzero -@item __sec_reduce_any_zero -@item __sec_reduce_any_nonzero -@item __sec_reduce -@item __sec_reduce_mutating -@end itemize +initialize builtin functions are stored in @file{array-notation-common.c}. @end itemize Detailed information about Cilk Plus and language specification is provided in diff --git gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c index 44e7361..4035ed5 100644 --- gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c +++ gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c @@ -1,16 +1,16 @@ int main(void) { extern int func(int); - int array3[:], x, q; /* { dg-error "array notations cannot be used in declaration." } */ - int array3[1:2:x]; /* { dg-error "array notations cannot be used in declaration." } */ - extern char array3[1:func(x)]; /* { dg-error "array notations cannot be used in declaration." } */ + int array3[:], x, q; /* { dg-error "array notations cannot be used in declaration" } */ + int array3[1:2:x]; /* { dg-error "array notations cannot be used in declaration" } */ + extern char array3[1:func(x)]; /* { dg-error "array notations cannot be used in declaration" } */ int *a, ***b; extern char *c; int array2[10]; - a[:] = 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 notations in pointers" } */ c[1:2] = 3; /* This is OK. */ (array2)[:] = 5; /* This is OK. */ - b[1:2][1:func(x)][:] = 3; /* { dg-error "start-index and length fields necessary for using array notations in pointers." } */ + b[1:2][1:func(x)][:] = 3; /* { dg-error "start-index and length fields necessary for using array notations in pointers" } */ } diff --git gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c index 272ef41..82008c0 100644 --- gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c +++ gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c @@ -3,16 +3,15 @@ typedef int (*foo)(int); int main(int argc, char **argv) { int array[10], array2[10][10]; - // int array[10], array2[10], value, ii = 0; foo func_array[10]; foo func_array2[10][10]; foo ***func_array_ptr; - 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); /* { 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" } */ return 0; } diff --git gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c index ef39b2b..59c2d1e 100644 --- gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c +++ gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c @@ -25,18 +25,18 @@ void func (int *x) int main2 (int argc, char **argv) { int array[10], array2[10]; - array2[:] = array[1.5:2]; /* { dg-error "start-index of array notation triplet is not an integer." } */ - array2[:] = array[1:2.32333333333]; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[1:2:1.5] = array[:]; /* { dg-error "stride of array notation triplet is not an integer." } */ - func (&array2[1:2.34:3]); /* { dg-error "length of array notation triplet is not an integer." } */ - array2[1.43:9]++; /* { dg-error "start-index of array notation triplet is not an integer." } */ - array2[1:9.3]++; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[1:9:0.3]++; /* { dg-error "stride of array notation triplet is not an integer." } */ + array2[:] = array[1.5:2]; /* { dg-error "start-index of array notation triplet is not an integer" } */ + array2[:] = array[1:2.32333333333]; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[1:2:1.5] = array[:]; /* { dg-error "stride of array notation triplet is not an integer" } */ + func (&array2[1:2.34:3]); /* { dg-error "length of array notation triplet is not an integer" } */ + array2[1.43:9]++; /* { dg-error "start-index of array notation triplet is not an integer" } */ + array2[1:9.3]++; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[1:9:0.3]++; /* { dg-error "stride of array notation triplet is not an integer" } */ - ++array2[1:q:3]; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[:] = array[q:1:3]; /* { dg-error "start-index of array notation triplet is not an integer." } */ - array2[:] = array[1:q:3]; /* { dg-error "length of array notation triplet is not an integer." } */ - array2[:] = array[1:3:q]; /* { dg-error "stride of array notation triplet is not an integer." } */ - func (&array2[1:q:3]); /* { dg-error "length of array notation triplet is not an integer." } */ + ++array2[1:q:3]; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[:] = array[q:1:3]; /* { dg-error "start-index of array notation triplet is not an integer" } */ + array2[:] = array[1:q:3]; /* { dg-error "length of array notation triplet is not an integer" } */ + array2[:] = array[1:3:q]; /* { dg-error "stride of array notation triplet is not an integer" } */ + func (&array2[1:q:3]); /* { dg-error "length of array notation triplet is not an integer" } */ return 0; } diff --git gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/misc.c gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/misc.c index 5a987d7..90a22eb 100644 --- gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/misc.c +++ gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/misc.c @@ -47,17 +47,17 @@ int main (int argc, char **argv) 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 "array notations 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 "array notations 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 "array notations cannot be used in a condition for a for-loop" } */ x = 4; diff --git gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c new file mode 100644 index 0000000..77955a3 --- /dev/null +++ gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c @@ -0,0 +1,23 @@ +int function_call (int x) +{ + return x; +} + +int main(int argc, char **argv) +{ + int array[100], array2[100][100]; + + array[:] = array[:] + array2[:][:]; /* { dg-error "rank mismatch in expression" } */ + + if (array[:] + array2[:][:]) /* { dg-error "rank mismatch in expression" } */ + return argc == 5; + + argc += function_call (array[:] + array2[5:10:2][:]); /* { dg-error "rank mismatch in expression" } */ + + argc += function_call (function_call (array[:] + array2[5:10:2][:])); /* { dg-error "rank mismatch in expression" } */ + + argc += __sec_reduce_add (array[:], array2[:][:]); /* { dg-error "rank mismatch in expression" } */ + + argc += __sec_reduce_add (array2[:][:]) + argc; /* This is OK. */ + return argc; +}