This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [patch] cilkplus array notation for C (clean, independent patchset, take 1)


Attached, please find a patch that should be applied to the head of cilkplus-merge. 
This patch is generated by diffing with the following hash: 4f4932be8230284919d197cccb4b10201f82a0b3

This patch also adds documentation about the built-in reduction funtions of array notations that Aldy pointed out in a previous email.

I have not fixed all the issues below (the big one that is left is the bultin function representation that Joseph Pointed out). I have fixed most of the other issues. All the things I have fixed are marked by "FIXED!"

Is this Ok to commit into cilkplus-merge?

Thanks,

Balaji V. Iyer.


> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Joseph S. Myers
> Sent: Thursday, March 21, 2013 11:56 AM
> To: Aldy Hernandez
> Cc: Iyer, Balaji V; gcc-patches
> Subject: Re: [patch] cilkplus array notation for C (clean, independent patchset,
> take 1)
> 
> On Wed, 20 Mar 2013, Aldy Hernandez wrote:
> 
> > Joseph, folks, et al... How does this look?
> 
> This review largely deals with coding style (interpreted broadly).  I'll review more
> of the substance separately later; reposting with fixes for all the accumulated
> issues is probably a good idea anyway, to avoid the same issues coming up
> repeatedly.
> 
> > 	* c-common.c (c_define_builtins): When cilkplus is enabled, the
> > 	function array_notation_init_builtins() is called.
> 
> Don't use () after a function name when referring to the function.

FIXED!

> 
> > diff --git a/gcc/c-family/array-notation-common.c
> > b/gcc/c-family/array-notation-common.c
> 
> > +int extract_sec_implicit_index_arg (location_t, tree); bool
> > +is_sec_implicit_index_fn (tree); void array_notation_init_builtins
> > +(void);

FIXED!

> 
> Non-static function declarations like this should not be inside a .c file.
> If these functions are used outside this file, there should be an associated
> header that declares them; include it in the .c file.  If only used inside the .c file
> that defines them, make them static (and topologically sort static functions
> inside a source file so that forward static declarations are only needed for cases
> of recursion).
> 
> > +/* Mark the FNDECL as cold, meaning that the function specified by FNDECL
> is
> > +   not run as is.  */
> 
> The cold attribute means unlikely to be executed rather than "not run as is".
> Maybe "not run as is" is what's relevant here, but I'm not clear why this attribute
> would be useful for built-in functions at all - the documentation suggests it's
> only relevant when a user defines a function themselves, and affects the code
> generated for that function, so wouldn't be relevant at all for built-in functions.
> 
> > +void
> > +array_notation_init_builtins (void)
> 
> Other built-in functions use various .def files (builtins.def and the files it includes)
> to avoid lots of repetitive code like this - can you integrate this with that
> mechanism?  If you do so, then you should be able to avoid (or massively
> simplify) functions like:
> 
> > +/* Returns true if the function call specified in FUNC_NAME is
> > +   __sec_implicit_index.  */
> > +
> > +bool
> > +is_sec_implicit_index_fn (tree func_name)
> 
> because code can use the BUILT_IN_* enum values to test whether a particular
> function is in use - which is certainly cleaner than using strcmp against the
> function name.
> 
> > +/* Returns the first and only argument for FN, which should be a
> > +   sec_implicit_index function.  FN's location in the source file is is
> > +   indicated by LOCATION.  */
> > +
> > +int
> > +extract_sec_implicit_index_arg (location_t location, tree fn) {
> > +  tree fn_arg;
> > +  HOST_WIDE_INT return_int = 0;
> > +  if (!fn)
> > +    return -1;
> 
> Why the random check for a NULL argument?  If a NULL argument is valid
> (meaning that it makes the code cleaner to allow such arguments rather than
> making sure the function isn't called with them), this should be documented in
> the comment above the function; otherwise, if such an argument isn't valid,
> there is no need to check for it.

I always tend to check for a null pointer before I access the fields in the structure. In this case it is unnecessary. In some cases (e.g. find_rank) there is a good chance a null pointer will be passed into the function and we need to check that and reject those.

> 
> You declare return_int as HOST_WIDE_INT, but it only receives a value cast to
> int, and is used only to store a value returned as int.  Either use int consistently,
> or HOST_WIDE_INT consistently, but I don't see a reason to use both.

FIXED!

> 
> > +  if (TREE_CODE (fn) == CALL_EXPR)
> > +    {
> > +      fn_arg = CALL_EXPR_ARG (fn, 0);
> > +      if (really_constant_p (fn_arg))
> 
> I don't think really_constant_p is what's wanted;
> <http://software.intel.com/sites/default/files/m/4/e/7/3/1/40297-
> Intel_Cilk_plus_lang_spec_2.htm>
> says "The argument shall be an integer constant expression.", and such
> expressions always appear in the C front end as INTEGER_CST.  So you can just
> check for INTEGER_CST.

What about C++? This function is shared by both C and C++.

> 
> Now a subtlety here is that the function argument will have been folded by this
> point, meaning that cases that aren't integer constant expressions in C standard
> terms will be wrongly allowed (both by the original code and by a version
> checking against INTEGER_CST).  In such cases, the way to get things checked
> correctly is to use a keyword rather than a built-in function - as with
> __builtin_choose_expr or __builtin_shuffle, for example.  Since this operation
> seems special in ways that built-in functions generally aren't, that seems
> reasonable anyway.  So the code parsing this keyword would check that the
> argument is an INTEGER_CST, of integer type (since INTEGER_CSTs can have
> pointer type in GCC), like that for __builtin_choose_expr does.  It would then
> quite likely create its own tree code for the operation, rather than using a
> CALL_EXPR at all.  (It would need to manage converting to int, given how the
> specification defines things in terms of a prototype for type int - so e.g. a
> constant 1ULL << 32 would act like 0 if int is 32 bits, under the present
> specification.)
> 
> The specification doesn't seem very clear on to what extent the __sec_*
> operations must act like functions (what happens if someone puts parentheses
> around the __sec_* name, for example - that wouldn't work with the keyword
> approach).  So the specification should be clarified there, but I think saying the
> __sec_* operations are syntactically special, like keywords, is more appropriate
> than requiring other uses to work.
> 
> > +	return_int = (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");
> 
> The term is "integer constant expression" not "constant integer expression".

FIXED!

> 
> > diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
> 
> > +void replace_array_notations (tree *, bool, vec<tree, va_gc> *,
> > +			      vec<tree, va_gc> *);
> > +void find_rank (tree, bool, size_t *); void
> > +extract_array_notation_exprs (tree, bool, vec<tree, va_gc> **); 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 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);
> 
> As before, forward declarations inside .c files should only be for static functions
> with recursive calls to themselves, not for non-static functions or static
> functions not involved in recursion.

FIXED!

> 
> > +struct inv_list
> > +{
> > +  vec<tree, va_gc> *list_values;
> > +  vec<tree, va_gc> *replacement;
> > +};
> 
> Comment on this type explaining what it's for.

FIXED!

> 
> > +/* 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).
> 
> The wording seems awkward; "Set *RANK to the rank of ARRAY, ignoring array-
> notation-specific built-in functions if IGNORE_BUILTIN_FN." would be better.

Yes, I agree with your wording. Thanks! and FIXED!

> 
> > +void
> > +find_rank (tree array, bool ignore_builtin_fn, size_t *rank) {
> > +  tree ii_tree;
> > +  size_t current_rank = 0, ii = 0;
> > +  an_reduce_type dummy_type = REDUCE_UNKNOWN;
> > +  if (!array)
> > +    return;
> 
> As before, avoid random checks for NULL parameters unless there is an actual
> reason to allow them and the comments document that they are allowed and
> what the semantics are in that case.  In general, explain what ARRAY is - an
> expression?

This check is necessary. Find rank can get a NULL pointer and that must be caught and rejected.

> 
> Is *RANK always set by this function?  Make clear in the comment above the
> function whether it is, and whether the initial value of *RANK before the
> function is called is of any significance.  I note that
> 
> > +  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;
> 
> does appear to look at the value before the function has set it, implying that the
> original value of *RANK *does* mean something.

FIXED! I looked this way due to an artifact of a previous implementation. It looks a little bit more cleaner now.

> 
> > +      if (TREE_CODE (array) == CALL_EXPR)
> > +	{
> > +	  tree func_name = CALL_EXPR_FN (array);
> > +	  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++)
> 
> TREE_INT_CST_LOW returns unsigned HOST_WIDE_INT.  There should be no
> need for converting twice, first to int and then to size_t.  And rather than
> depending on implementation default of CALL_EXPR, call_expr_nargs would be
> a better way to calculate the length.
> 
> > +		find_rank (TREE_OPERAND (array, ii), ignore_builtin_fn, rank);
> 
> But actually, you're dealing with a CALL_EXPR here.  So you should be able to
> use existing iterators over CALL_EXPR arguments (e.g.
> FOR_EACH_CALL_EXPR_ARG) rather than explicitly using the number of
> arguments at all.  Doing so, and separately checking CALL_EXPR_FN, and
> CALL_EXPR_STATIC_CHAIN if applicable, seems cleaner than depending on low-
> level details of the sequence of operands to a CALL_EXPR.

FIXED! (I used your suggestion and used FOR_EACH_CALL_EXPR_ARG)


> 
> > +/* 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).  */
> > +
> > +void
> > +extract_array_notation_exprs (tree node, bool ignore_builtin_fn,
> > +			      vec<tree, va_gc> **array_list)
> 
> There's no argument LIST_SIZE, so the comment needs updating.  Again, the
> wording about "The user" is awkward; the comment should directly define the
> semantics of the function in terms of its argument, without reference to "The
> user".

FIXED! Reworded the comment.

> 
> > +{
> > +  size_t ii = 0;
> > +  an_reduce_type dummy_type = REDUCE_UNKNOWN;
> > +
> > +  if (!node)
> > +    return;
> 
> Again, check for NULL argument without any mention in the comment that such
> arguments are valid; remove unless there is a reason to make them valid.
> 
> > +  else if (TREE_CODE (node) == TREE_LIST)
> 
> What's NODE?  My first guess would have been an expression, but if a TREE_LIST
> is possible that's clearly not the answer, so explain in the comment above the
> function what NODE is.  (If a TREE_LIST is being used within expressions to store
> something specific to array notation, don't do so - TREE_LIST is deprecated,
> existing uses should be phased out in favour of more specific and less memory-
> hungry datastructures and new uses should not be added.)

FIXED! What is replacing tree-list? I have used tree-list in my later patches and in my Cilk Plus branch.

> 
> > +      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);
> 
> Same problems as before with an iterator over CALL_EXPR that should avoid
> depending on low-level details of how CALL_EXPR is implemented, and excess
> integer type conversions.

FIXED!

> 
> > +/* 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).  */
> 
> Again, avoid "The user".

FIXED!

> 
> > +void
> > +replace_array_notations (tree *orig, bool ignore_builtin_fn,
> > +			 vec<tree, va_gc> *list,
> > +			 vec<tree, va_gc> *array_operand)
> > +{
> > +  size_t ii = 0;
> > +  tree node = NULL_TREE, node_replacement = NULL_TREE;
> > +  an_reduce_type dummy_type = REDUCE_UNKNOWN;
> > +
> > +  if (vec_safe_length (list) == 0 || !*orig)
> > +    return;

This ORIG must be checked for NULL because you will step this function even if the node is NULL. This is the spot to check that.

> 
> Again, avoid checks for NULL or document that NULL arguments are valid if
> there's a good reason.  Generally, document what sort of thing ORIG is.
> 
> > +      if (TREE_CODE (TREE_OPERAND (*orig, 0)) == INTEGER_CST)
> > +	{
> > +	  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);
> 
> Again, better CALL_EXPR iterators.

FIXED!

> 
> > +/* 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.  */
> 
> Rather than "This function will", just "Find ..." (and say "Returns NULL_TREE." or
> something like that - presumably the return type is so it can be passed to
> walk_tree).
> 
> > +/* Replaces all the scalar expressions in *NODE. */
> > +
> > +tree
> > +replace_invariant_exprs (tree *node)
> 
> Comment needs to explain the semantics of the return value.

FIXED! 

> 
> > +tree
> > +build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
> > +			   enum tree_code modifycode, location_t rhs_loc,
> > +			   tree rhs, tree rhs_origtype)
> 
> > +    }
> > +
> > +
> > +
> > +  for (ii = 0; ii < lhs_rank; ii++)
> 
> Excess blank lines in middle of function.  Generally there shouldn't be two or
> more consecutive blank lines inside a function (if you want to have different
> sizes of blanks to split up levels of structure in the function, that suggests the
> function is too big and should be split up into separate functions).

FIXED!

> 
> > +	     TREE_TYPE (lhs_var[ii]));
> > +
> > +	}
> 
> This location for a blank line doesn't make sense.

FIXED!

> 
> > +  /* The following statements will do the following:
> > +   * <if_stmt_label>: (in order from outermost to innermost)
> > +   *                  if (cond_expr) then go to body_label
> > +   *                  else                go to exit_label
> > +   * <body_label>:
> > +   *                  array expression
> > +   *
> > +   *                  (the increment, goto and exit_label goes from innermost to
> > +   *                   outermost).
> > +   *                  ii++ and jj++
> > +   *                  go to if_stmt_label
> > +   * <exit_label>:
> > +   *                  <REST OF CODE>
> > +   */
> 
> Comments should not have an initial "*" on each line.

FIXED!

> 
> > +/* 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.  */
> > +
> > +static tree
> > +fix_conditional_array_notations_1 (tree stmt)
> 
> Comment should explain return value semantics.

FIXED!

> 
> > +			   TREE_TYPE (array_var[ii]));
> > +
> > +    }
> 
> Another stray blank line.  Check the patch generally for stray blank lines
> immediately before a '}', I don't think they ever make sense, but I may have
> missed some.

I think I have caught all of it. I apologize if I missed any.

> 
> > +  // XDELETEVEC (array_var);
> 
> I don't think this sort of commented-out code should be added.  If you're
> deliberately not doing something that a reader might expect to be done, have a
> comment explaining *why* you're not doing it, not just commented-out code to
> do it.

FIXED!

> 
> > +      error_at (location, "__sec_reduce_min_ind or __sec_reduce_max_ind
> cannot"
> > +		" have arrays with dimension greater than 1.");
> 
> Diagnostics don't end with ".".
> 
> > +    default:
> > +      gcc_unreachable ();  /* You should not reach here.  */
> 
> No need for comments like this that just repeat the plain semantics of the C
> code.  There's nothing else a call to gcc_unreachable could possibly mean; such
> a comment is of no more use than "i++; /* Add 1 to i.  */".

FIXED!

> 
> > +/* Returns true of FUNC_NAME is a builtin array notation function.  The type
> of
> > +   function is returned in *TYPE.  */
> 
> "true if", not "true of".
> 

FIXED! Sorry for this stupid mistake.

> > +bool
> > +is_builtin_array_notation_fn (tree func_name, an_reduce_type *type) {
> > +  const char *function_name = NULL;
> > +
> > +  if (!func_name)
> > +    return false;
> 
> Another unexplained test for a NULL argument.  Again, explain what sort of
> things FUNC_NAME may be.  (This is another function that should be using
> BUILT_IN_* enum values rather than strcmp, if you rework how the built-in
> functions are implemented.)
> 
> > +/* Returns true of EXPR (and its subtrees) contain
> > +ARRAY_NOTATION_EXPR node.  */
> 
> "true if", again.

FIXED!


> 
> > +/* 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.  */
> 
> LOOP is not an argument to this function, so it doesn't make sense to refer to it
> in the comment.  I suspect " in a tree node variable called LOOP" should simply
> be removed.

FIXED!

> 
> > +  if (TREE_CODE (arg) == CALL_EXPR
> > +      && is_builtin_array_notation_fn (CALL_EXPR_FN (arg), &an_type))
> > +    {
> > +      loop = fix_builtin_array_notation_fn (arg, &new_var);
> > +      /* We are ignoring the new var because either the user does not want to
> > +	 capture it OR he is using sec_reduce_mutating function.  */
> 
> In general I think "the user" comments should be avoided though this one is a bit
> less awkward than those defining function semantics by reference to "the user".
> 
> > +/* 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.  */
> > +
> > +tree
> > +expand_array_notation_exprs (tree t)
> 
> Comment should document return value.

FIXED!

> 
> > +{
> > +  if (!t || !contains_array_notation_expr (t))
> > +    return t;
> 
> Another check for NULL without a comment saying NULL is a valid argument.

This function also can receive a null pointer.

> 
> > +/* Returns array notation expression for the array base ARRAY of type TYPE,
> > +   with start index, length and stride given by START_INDEX, LENGTH and
> STRIDE,
> > +   respectively.  */
> > +
> > +tree
> > +build_array_notation_ref (location_t loc, tree array, tree start_index,
> > +			  tree length, tree stride, tree type) {
> > +  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)))
> 
> I'd expect the argument would have to be an expression, so would always have
> a TYPE and the !TREE_TYPE (start_index) check should be unnecessary.
> If it is needed, explain further in the comment at the start of the function.
> Likewise for other checks for NULL types in this function.

FIXED! But Stride could easily be NULL, (e.g. array[0:10]) and in this case we have put one in. So, I have left that check in.
> 
> > +    {
> > +      error_at (loc,
> > +		"start-index of array notation triplet is not an integer.");
> 
> Diagnostic should not end with ".".

FIXED!

> 
> > +      error_at (loc, "length of array notation triplet is not an
> > + integer.");
> 
> Likewise.

FIXED!

> 
> > +      error_at (loc, "stride of array notation triplet is not an
> > + integer.");
> 
> Likewise.

FIXED!

> 
> > +      error_at (loc, "rank of an array notation triplet's start-index is not "
> > +		"zero.");
> 
> Likewise.

FIXED!

> 
> > +      error_at (loc, "rank of an array notation triplet's length is
> > + not zero.");
> 
> Likewise.

FIXED!

> 
> > +      error_at (loc, "rank of array notation triplet's stride is not
> > + zero.");
> 
> Likewise.

FIXED!

> 
> That's a coding style review of the first half or so of the patch, more later....

Thanks for reviewing my code!

-Balaji V. Iyer.

> 
> --
> Joseph S. Myers
> joseph@codesourcery.com
diff --git a/gcc/c-family/ChangeLog.cilkplus b/gcc/c-family/ChangeLog.cilkplus
index 6591fd1..10db29b 100644
--- a/gcc/c-family/ChangeLog.cilkplus
+++ b/gcc/c-family/ChangeLog.cilkplus
@@ -1,7 +1,11 @@
+2013-03-22  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* c-pretty-print.c (pp_c_expression): Added ARRAY_NOTATION_REF case.
+
 2013-03-20  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* 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.
diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c
index 7089c8e..b775225 100644
--- a/gcc/c-family/array-notation-common.c
+++ b/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 a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index edcff2e..e07085d 100644
--- a/gcc/c-family/c-common.h
+++ b/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);
 
 #endif /* ! GCC_C_COMMON_H */
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 30c8e80..b8af90c 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/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 a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
old mode 100644
new mode 100755
index a3e754a..3d36382
--- a/gcc/c/c-array-notation.c
+++ b/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<tree, va_gc> *,
+static void replace_array_notations (tree *, bool, vec<tree, va_gc> *,
 			      vec<tree, va_gc> *);
-void find_rank (tree, bool, size_t *);
-void extract_array_notation_exprs (tree, bool, vec<tree, va_gc> **);
-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<tree, va_gc> **);
+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 that comes with array notation 
+   expressions.  */
 struct inv_list
 {
   vec<tree, va_gc> *list_values;
@@ -51,72 +49,80 @@ 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).
+/* Sets *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.  
 
    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 ans stores 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.  */
 
-void
+static void
 extract_array_notation_exprs (tree node, bool ignore_builtin_fn,
 			      vec<tree, va_gc> **array_list)
 {
@@ -148,6 +154,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 +171,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 +183,12 @@ 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.  */
 
-void
+static void
 replace_array_notations (tree *orig, bool ignore_builtin_fn,
 			 vec<tree, va_gc> *list,
 			 vec<tree, va_gc> *array_operand)
@@ -200,7 +197,7 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn,
   tree node = NULL_TREE, node_replacement = NULL_TREE;
   an_reduce_type dummy_type = REDUCE_UNKNOWN;
   
-  if (vec_safe_length (list) == 0 || !*orig)
+  if (!*orig || vec_safe_length (list) == 0)
     return;
 
   if (TREE_CODE (*orig) == ARRAY_NOTATION_REF)
@@ -221,6 +218,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 +243,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 +261,9 @@ 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 it in DATA struct, 
+   typecasted to (void *).  If *WALK_SUBTREES is set to 0 then do not go into 
+   the *TP's subtrees.  */
 
 static tree
 find_inv_trees (tree *tp, int *walk_subtrees, void *data)
@@ -322,7 +319,9 @@ 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.  */
 
 tree
 replace_invariant_exprs (tree *node)
@@ -391,13 +390,16 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   tree ii_tree = NULL_TREE, new_modify_expr;
   vec<tree, va_gc> *lhs_list = NULL, *rhs_list = NULL;
   tree new_var = NULL_TREE, builtin_loop = NULL_TREE;
+  tree begin_var, lngth_var, strde_var;
   size_t rhs_list_size = 0, lhs_list_size = 0;
 
   /* If either of this is true, an error message must have been send out
      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);
@@ -434,8 +436,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)
     {
@@ -466,12 +471,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)
     {
@@ -491,6 +506,72 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
       return error_mark_node;
     }
   
+  /* Here we assign the array notation components to variable so that we can
+     satisfy the exec once rule.  */
+  for (ii = 0; ii < lhs_list_size; ii++)
+    {
+      tree array_node = (*lhs_list)[ii];
+      tree array_begin = ARRAY_NOTATION_START (array_node);
+      tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+      tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+      
+      begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+			      integer_type_node);
+      lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+			      integer_type_node);
+      strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+			      integer_type_node);
+
+      add_stmt (build_modify_expr (location, begin_var, TREE_TYPE (begin_var),
+				   NOP_EXPR, location, array_begin,
+				   TREE_TYPE (array_begin)));
+      add_stmt (build_modify_expr (location, lngth_var, TREE_TYPE (lngth_var),
+				   NOP_EXPR, location, array_lngth,
+				   TREE_TYPE (array_lngth)));
+      add_stmt (build_modify_expr (location, strde_var, TREE_TYPE (strde_var),
+				   NOP_EXPR, location, array_strde,
+				   TREE_TYPE (array_strde)));
+      
+      ARRAY_NOTATION_START (array_node) = begin_var;
+      ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+      ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+    }
+
+  for (ii = 0; ii < rhs_list_size; ii++)
+    {
+      tree array_node = (*rhs_list)[ii];
+      if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+	{
+	  tree array_begin = ARRAY_NOTATION_START (array_node);
+	  tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+	  tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+
+	  begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+	  lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+	  strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+
+	  add_stmt (build_modify_expr (location, begin_var,
+				       TREE_TYPE (begin_var),
+				       NOP_EXPR, location, array_begin,
+				       TREE_TYPE (array_begin)));
+	  add_stmt (build_modify_expr (location, lngth_var,
+				       TREE_TYPE (lngth_var),
+				       NOP_EXPR, location, array_lngth,
+				       TREE_TYPE (array_lngth)));
+	  add_stmt (build_modify_expr (location, strde_var,
+				       TREE_TYPE (strde_var),
+				       NOP_EXPR, location, array_strde,
+				       TREE_TYPE (array_strde)));
+      
+	  ARRAY_NOTATION_START (array_node) = begin_var;
+	  ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+	  ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+	}
+    }
+  
   lhs_vector = XNEWVEC (bool *, lhs_list_size);
   for (ii = 0; ii < lhs_list_size; ii++)
     lhs_vector[ii] = XNEWVEC (bool, lhs_rank);
@@ -678,8 +759,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])
@@ -691,7 +770,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]));
-	  
 	}
     }
 
@@ -965,19 +1043,19 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
     }
   
   /* The following statements will do the following:
-   * <if_stmt_label>: (in order from outermost to innermost)
-   *                  if (cond_expr) then go to body_label
-   *                  else                go to exit_label
-   * <body_label>:
-   *                  array expression
-   *
-   *                  (the increment, goto and exit_label goes from innermost to
-   *                   outermost).
-   *                  ii++ and jj++
-   *                  go to if_stmt_label
-   * <exit_label>:
-   *                  <REST OF CODE>
-   */
+     <if_stmt_label>: (in order from outermost to innermost)
+                      if (cond_expr) then go to body_label
+                      else                go to exit_label
+     <body_label>:
+                      array expression
+   
+     (the increment, goto and exit_label goes from innermost to
+     outermost).
+                      ii++ and jj++
+                      go to if_stmt_label
+     <exit_label>:
+     <REST OF CODE>
+  */
 
   
   for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
@@ -1012,7 +1090,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)
@@ -1027,8 +1107,9 @@ fix_conditional_array_notations_1 (tree stmt)
   tree *body_label, *body_label_expr, *exit_label, *exit_label_expr;
   tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init;
   bool **count_down, **array_vector;
+  tree begin_var, lngth_var, strde_var;
   location_t location = UNKNOWN_LOCATION;
-
+  
   if (TREE_CODE (stmt) == COND_EXPR)
     cond = COND_EXPR_COND (stmt);
   else if (TREE_CODE (stmt) == SWITCH_EXPR)
@@ -1037,7 +1118,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++)
@@ -1062,7 +1147,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);
@@ -1076,7 +1163,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++)
@@ -1115,6 +1201,42 @@ fix_conditional_array_notations_1 (tree stmt)
 
   array_var = XNEWVEC (tree, rank);
 
+  
+  for (ii = 0; ii < list_size; ii++)
+    {
+      tree array_node = (*array_list)[ii];
+      if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+	{
+	  tree array_begin = ARRAY_NOTATION_START (array_node);
+	  tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+	  tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
+
+	  begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+	  lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+	  strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+
+	  add_stmt (build_modify_expr (location, begin_var,
+				       TREE_TYPE (begin_var),
+				       NOP_EXPR, location, array_begin,
+				       TREE_TYPE (array_begin)));
+	  add_stmt (build_modify_expr (location, lngth_var,
+				       TREE_TYPE (lngth_var),
+				       NOP_EXPR, location, array_lngth,
+				       TREE_TYPE (array_lngth)));
+	  add_stmt (build_modify_expr (location, strde_var,
+				       TREE_TYPE (strde_var),
+				       NOP_EXPR, location, array_strde,
+				       TREE_TYPE (array_strde)));
+      
+	  ARRAY_NOTATION_START (array_node) = begin_var;
+	  ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+	  ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+	}
+    }
+  
   for (ii = 0; ii < list_size; ii++)
     {
       tree array_node = (*array_list)[ii];
@@ -1174,7 +1296,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++)
@@ -1291,7 +1412,6 @@ fix_conditional_array_notations_1 (tree stmt)
   XDELETEVEC (if_stmt_label);
   XDELETEVEC (expr_incr);
   XDELETEVEC (ind_init);
-  // XDELETEVEC (array_var);
   
   for (ii = 0; ii < list_size; ii++)
     {
@@ -1354,7 +1474,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;
   
@@ -1413,6 +1541,8 @@ fix_array_notation_expr (location_t location, enum tree_code code,
 	  jj++;
 	}
     }
+  
+  loop = push_stmt_list ();
 
   for (ii = 0; ii < list_size; ii++)
     {
@@ -1451,8 +1581,6 @@ fix_array_notation_expr (location_t location, enum tree_code code,
 	}
     }
 
-  loop = push_stmt_list ();
-
   for (ii = 0; ii < rank; ii++)
     {
       array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
@@ -1531,12 +1659,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++)
     {
@@ -1553,7 +1679,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++)
     {
@@ -1669,10 +1794,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;
@@ -1680,7 +1806,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;
     }
   
@@ -1712,7 +1838,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);
@@ -1879,12 +2005,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++)
     {
@@ -2218,10 +2343,10 @@ 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;
@@ -2310,7 +2435,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)
@@ -2331,9 +2456,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)
@@ -2347,6 +2471,7 @@ fix_array_notation_call_expr (tree arg)
   tree *body_label, *body_label_expr, *exit_label, *exit_label_expr;
   tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init;
   bool **count_down, **array_vector;
+  tree begin_var, lngth_var, strde_var;
   an_reduce_type an_type = REDUCE_UNKNOWN;
   location_t location = UNKNOWN_LOCATION;
 
@@ -2359,12 +2484,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;
   
@@ -2407,7 +2533,42 @@ fix_array_notation_call_expr (tree arg)
     count_down[ii] = XNEWVEC (bool, rank);
   
   array_var = XNEWVEC (tree, rank);
+  
+  loop = push_stmt_list ();
+  for (ii = 0; ii < list_size; ii++)
+    {
+      tree array_node = (*array_list)[ii];
+      if (array_node && TREE_CODE (array_node) == ARRAY_NOTATION_REF)
+	{
+	  tree array_begin = ARRAY_NOTATION_START (array_node);
+	  tree array_lngth = ARRAY_NOTATION_LENGTH (array_node);
+	  tree array_strde = ARRAY_NOTATION_STRIDE (array_node);
 
+	  begin_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+	  lngth_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+	  strde_var = build_decl (location, VAR_DECL, NULL_TREE,
+				  integer_type_node);
+
+	  add_stmt (build_modify_expr (location, begin_var,
+				       TREE_TYPE (begin_var),
+				       NOP_EXPR, location, array_begin,
+				       TREE_TYPE (array_begin)));
+	  add_stmt (build_modify_expr (location, lngth_var,
+				       TREE_TYPE (lngth_var),
+				       NOP_EXPR, location, array_lngth,
+				       TREE_TYPE (array_lngth)));
+	  add_stmt (build_modify_expr (location, strde_var,
+				       TREE_TYPE (strde_var),
+				       NOP_EXPR, location, array_strde,
+				       TREE_TYPE (array_strde)));
+      
+	  ARRAY_NOTATION_START (array_node) = begin_var;
+	  ARRAY_NOTATION_LENGTH (array_node) = lngth_var;
+	  ARRAY_NOTATION_STRIDE (array_node) = strde_var;
+	}
+    }
   for (ii = 0; ii < list_size; ii++)
     {
       jj = 0;
@@ -2457,8 +2618,6 @@ fix_array_notation_call_expr (tree arg)
 	}
     }
 
-  loop = push_stmt_list ();
-
   for (ii = 0; ii < rank; ii++)
     {
       array_var[ii] = build_decl (location, VAR_DECL, NULL_TREE,
@@ -2610,7 +2769,9 @@ 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.  */
 
 tree
 expand_array_notation_exprs (tree t)
@@ -2665,20 +2826,20 @@ 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))))
+  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)
@@ -2690,24 +2851,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;
     }
   
@@ -2747,4 +2911,3 @@ find_correct_array_notation_type (tree op)
     } 
   return return_type;
 }
-
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index ba0a7f9..2ca5a3a 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -11052,14 +11052,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 +11074,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 +11086,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,7 +11098,7 @@ 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;
 	    }
@@ -11120,7 +11120,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 +11138,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 a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 15dc83d..cb2fe4a 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2309,7 +2309,8 @@ build_array_ref (location_t loc, tree array, tree index)
   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.");
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 627bf69..3ce9969 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -82,6 +82,8 @@ 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 that are part of 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 +8764,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 a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c
index 5fb3680..fd128b1 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/array_test2.c
@@ -26,7 +26,7 @@ int main(int argc, char **argv)
       array[ii] = 10;
       array2[ii] = 5000000;
     }
-  array2[0:10:2] = array[0:10:2];
+  array2[0:5:2] = array[0:5:2];
 
   printf("==============================================\n");
   for (ii = 0; ii<10; ii++)
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/cilkplus_AN_c_compile.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/cilkplus_AN_c_compile.exp
new file mode 100644
index 0000000..a965997
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/cilkplus_AN_c_compile.exp
@@ -0,0 +1,34 @@
+#   Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+
+load_lib gcc-dg.exp
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/compile.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/compile.exp
deleted file mode 100644
index 6d7604b..0000000
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/compile/compile.exp
+++ /dev/null
@@ -1,65 +0,0 @@
-#   Copyright (C) 2013 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-
-
-load_lib gcc-dg.exp
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " "
-dg-finish
-
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
-dg-finish
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/cilkplus_AN_c_errors.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/cilkplus_AN_c_errors.exp
new file mode 100644
index 0000000..a965997
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/cilkplus_AN_c_errors.exp
@@ -0,0 +1,34 @@
+#   Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+
+load_lib gcc-dg.exp
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c
index 44e7361..4035ed5 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/decl-ptr-colon.c
+++ b/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 a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/errors.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/errors.exp
deleted file mode 100644
index 6d7604b..0000000
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/errors.exp
+++ /dev/null
@@ -1,65 +0,0 @@
-#   Copyright (C) 2013 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-# Written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-
-
-load_lib gcc-dg.exp
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O0 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O1 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -O3 -fcilkplus" " "
-dg-finish
-
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O0 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O1 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] " -g -O3 -fcilkplus" " "
-dg-finish
-
-dg-init
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/array_notation_tests/errors/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
-dg-finish
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c
index 272ef41..82008c0 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fn_ptr.c
+++ b/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 a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c
index ef39b2b..59c2d1e 100644
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/fp_triplet_values.c
+++ b/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 a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/errors/rank_mismatch2.c
new file mode 100644
index 0000000..77955a3
--- /dev/null
+++ b/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;
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/cilkplus_AN_c_execute.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/cilkplus_AN_c_execute.exp
new file mode 100644
index 0000000..37d22c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/cilkplus_AN_c_execute.exp
@@ -0,0 +1,60 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# This file was written by Balaji V. Iyer <balaji.v.iyer@intel.com>
+# Many thanks to the GCC C-torture contributors.
+
+verbose "$tool $libdir" 1
+
+set library_var [get_multilibs]
+dg-init
+set CILK_TORTURE_OPTIONS [list \
+			   { -O0 -fcilkplus  -std=c99} \
+			   { -O1 -fcilkplus  -std=c99} \
+			   { -O2 -fcilkplus  -std=c99} \
+			   { -O3 -fcilkplus  -fomit-frame-pointer -funroll-loops -std=c99} \
+			   { -O3 -fcilkplus  -fomit-frame-pointer -funroll-all-loops -finline-functions -std=c99 } \
+			   { -O3 -fcilkplus  -fomit-frame-pointer -funroll-all-loops -finline-functions -ftree-vectorize -std=c99 } \
+			   { -O3 -g -fcilkplus  -std=c99} \
+			   { -Os -fcilkplus  -std=c99} ]
+
+
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+# load support procs
+load_lib torture-options.exp
+load_lib c-torture.exp
+
+torture-init
+set-torture-options $CILK_TORTURE_OPTIONS {{}} $CILK_TORTURE_OPTIONS
+
+#
+# main test loop
+#
+
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]]  {
+    # If we're only testing specific files and this isn't one of them, skip it.
+    if ![runtest_file_p $runtests $src] then {
+	continue
+    }
+
+    c-torture-execute $src
+}
+
+torture-finish
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/exec-once2.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/exec-once2.c
new file mode 100644
index 0000000..ba70ab8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/exec-once2.c
@@ -0,0 +1,82 @@
+#ifdef HAVE_IO
+#include <stdio.h>
+#endif
+
+
+int func1(int x)
+{
+  /* If x == 2 then it should return 0.  */
+  return (x - 2);
+}
+
+int func2(int x)
+{
+  /* If x == 2 then it should return 1000.  */
+  return (x * 500);
+}
+
+int func3 (int x)
+{
+  /* If x == 2 then it should return 1.  */
+  /* If x == 1 then it should return 0.  */
+  return (x-1);
+}
+
+int func4(int x)
+{
+  if (x > 0) 
+    return x;
+  else 
+    return x--;
+}
+
+
+/* This program makes an assumption that argc == 1.  */
+int main (int argc, char **argv)
+{
+
+  int array[2500];
+
+  /* This should set array[0->999] to 5.  */
+  array[argc-1:func2(++argc):1] = 5;
+  array[1000:500:1] = 10; /* set all variables in array[1000-->1499] to 10.  */
+  array[1500:500:1] = 15; /* set all variables in array[1500-->1999] to 15.  */
+  array[2000:500:1] = 20; /* set all variables in array[2000-->2499] to 20.  */
+  array[2000:500:1] = 25; /* set all variables in array[2500-->2999] to 25.  */
+  array[2000:500:1] = 30; /* set all variables in array[3000-->3499] to 30.  */
+  
+  argc = func3 (argc); /* This will set argc back to 1.  */
+#if HAVE_IO
+  printf("argc = %d\n", argc);
+#endif
+  /* If the parameters inside the function get evaluated only once, then this
+     if statement must work fine, i.e. the triplet values will be 0, 1000, 1.
+
+     Otherwise, the program should crash or give some uneasy value.  */
+
+  /* If done correctly, it should boil down to: array[0:1000:1].  */
+  if (array[func3(argc):func2(++argc)] != 5) {
+#ifdef HAVE_IO
+    printf ("Should not be there(1).\n");
+#endif
+    return 1;
+  }
+  
+  /* If done correctly, it should boil down to: array[999:500:-1].  */
+  if (func4(array[func2(argc)-1:func2(argc--):func1(argc)]) != 5) {
+#ifdef HAVE_IO
+    printf ("Should not be there(2).\n");
+#endif
+    return 1;
+  }
+
+  /* If done correctly, it should boil down to: array[1000:500:1].  */
+  if (func4 (func4(array[func2(argc++):500: func1(argc--)])) != 5) {
+#ifdef HAVE_IO
+    printf ("Should not be there(3).\n");
+#endif
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/execute.exp b/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/execute.exp
deleted file mode 100644
index 37d22c5..0000000
--- a/gcc/testsuite/gcc.dg/cilk-plus/array_notation/execute/execute.exp
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2013 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-# This file was written by Balaji V. Iyer <balaji.v.iyer@intel.com>
-# Many thanks to the GCC C-torture contributors.
-
-verbose "$tool $libdir" 1
-
-set library_var [get_multilibs]
-dg-init
-set CILK_TORTURE_OPTIONS [list \
-			   { -O0 -fcilkplus  -std=c99} \
-			   { -O1 -fcilkplus  -std=c99} \
-			   { -O2 -fcilkplus  -std=c99} \
-			   { -O3 -fcilkplus  -fomit-frame-pointer -funroll-loops -std=c99} \
-			   { -O3 -fcilkplus  -fomit-frame-pointer -funroll-all-loops -finline-functions -std=c99 } \
-			   { -O3 -fcilkplus  -fomit-frame-pointer -funroll-all-loops -finline-functions -ftree-vectorize -std=c99 } \
-			   { -O3 -g -fcilkplus  -std=c99} \
-			   { -Os -fcilkplus  -std=c99} ]
-
-
-
-if $tracelevel then {
-    strace $tracelevel
-}
-
-# load support procs
-load_lib torture-options.exp
-load_lib c-torture.exp
-
-torture-init
-set-torture-options $CILK_TORTURE_OPTIONS {{}} $CILK_TORTURE_OPTIONS
-
-#
-# main test loop
-#
-
-foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]]  {
-    # If we're only testing specific files and this isn't one of them, skip it.
-    if ![runtest_file_p $runtests $src] then {
-	continue
-    }
-
-    c-torture-execute $src
-}
-
-torture-finish

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]