diff --git a/gcc/builtins.def b/gcc/builtins.def
index 91879a6..9b55b1f 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -158,9 +158,9 @@ along with GCC; see the file COPYING3.  If not see
 	       (flag_asan || flag_tsan))
 
 #undef DEF_CILKPLUS_BUILTIN
-#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
-  DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
-  	       false, false, true, ATTRS, false, flag_enable_cilkplus)
+#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS)  \
+  DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
+  	       false, false, false, ATTRS, false, flag_enable_cilkplus) 
 
 /* Define an attribute list for math functions that are normally
    "impure" because some of them may write into global memory for
diff --git a/gcc/c-family/array-notation-common.c b/gcc/c-family/array-notation-common.c
index 8eab89b..5e17009 100644
--- a/gcc/c-family/array-notation-common.c
+++ b/gcc/c-family/array-notation-common.c
@@ -101,15 +101,11 @@ length_mismatch_in_expr_p (location_t loc, vec<vec<an_parts> >list)
 	      /* If length is a INTEGER, and list[ii][jj] is an integer then
 		 check if they are equal.  If they are not equal then return
 		 true.  */
-	      if (TREE_CODE (list[ii][jj].length) == INTEGER_CST)
-		{
-		  l_node = int_cst_value (list[ii][jj].length);
-		  l_length = int_cst_value (length);
-		  if (absu_hwi (l_length) != absu_hwi (l_node))
-		    {
-		      error_at (loc, "length mismatch in expression");
-		      return true;
-		    }
+	      if (TREE_CODE (list[ii][jj].length) == INTEGER_CST
+		  && !tree_int_cst_equal (list[ii][jj].length, length))
+		{ 
+		  error_at (loc, "length mismatch in expression"); 
+		  return true;
 		}
 	    }
 	  else
@@ -271,6 +267,8 @@ find_rank (location_t loc, tree orig_expr, tree expr, bool ignore_builtin_fn,
 		/* If it is a built-in function, then we know it returns a 
 		   scalar.  */
 		return true;
+	  if (!find_rank (loc, orig_expr, func_name, ignore_builtin_fn, rank))
+	    return false;
 	  FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
 	    {
 	      if (!find_rank (loc, orig_expr, arg, ignore_builtin_fn, rank))
@@ -358,6 +356,9 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn,
 	  vec_safe_push (*array_list, node);
 	  return;
 	}
+      /* This will extract array notations in function pointers.  */
+      extract_array_notation_exprs (CALL_EXPR_FN (node), ignore_builtin_fn,
+				    array_list);
       FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
 	extract_array_notation_exprs (arg, ignore_builtin_fn, array_list);
     } 
@@ -433,6 +434,9 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn,
 	      }
 	  return;
 	}
+      /* Fixes array notations in array notations in function pointers.  */
+      replace_array_notations (&CALL_EXPR_FN (*orig), ignore_builtin_fn, list,
+			       array_operand);
       ii = 0;
       FOR_EACH_CALL_EXPR_ARG (arg, iter, *orig)
 	{
@@ -575,53 +579,49 @@ cilkplus_extract_an_triplets (vec<tree, va_gc> *list, size_t size, size_t rank,
 			      vec<vec<struct cilkplus_an_parts> > *node)
 {
   vec<vec<tree> > array_exprs = vNULL;
-  struct cilkplus_an_parts init = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
-				    false };
+
   node->safe_grow_cleared (size);
   array_exprs.safe_grow_cleared (size);
-  for (size_t ii = 0; ii < size; ii++)
-    for (size_t jj = 0; jj < rank; jj++)
+
+  if (rank > 0)
+    for (size_t ii = 0; ii < size; ii++)
       {
-	(*node)[ii].safe_push (init);
-	array_exprs[ii].safe_push (NULL_TREE);
+	(*node)[ii].safe_grow_cleared (rank);
+	array_exprs[ii].safe_grow_cleared (rank);
       }
-
   for (size_t ii = 0; ii < size; ii++)
     {
       size_t jj = 0;
       tree ii_tree = (*list)[ii];
       while (ii_tree)
-	if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
-	  {
-	    array_exprs[ii][jj] = ii_tree;
-	    jj++;
-	    ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
-	  }
-	else if (TREE_CODE (ii_tree) == ARRAY_REF)
-	  ii_tree = TREE_OPERAND (ii_tree, 0);
-	else if (TREE_CODE (ii_tree) == VAR_DECL
-		 || TREE_CODE (ii_tree) == CALL_EXPR
-		 || TREE_CODE (ii_tree) == PARM_DECL)
-	  break;
-	else
-	  gcc_unreachable ();	
+	{
+	  if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
+	    {
+	      array_exprs[ii][jj] = ii_tree;
+	      jj++;
+	      ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
+	    }
+	  else if (TREE_CODE (ii_tree) == ARRAY_REF)
+	    ii_tree = TREE_OPERAND (ii_tree, 0);
+	  else
+	    break;
+	}
     }
     for (size_t ii = 0; ii < size; ii++)
       if (TREE_CODE ((*list)[ii]) == ARRAY_NOTATION_REF)
 	for (size_t jj = 0; jj < rank; jj++)
-	  if (TREE_CODE (array_exprs[ii][jj]) == ARRAY_NOTATION_REF)
-	    {
-	      tree ii_tree = array_exprs[ii][jj];
-	      (*node)[ii][jj].is_vector = true;
-	      (*node)[ii][jj].value = ARRAY_NOTATION_ARRAY (ii_tree);
-	      (*node)[ii][jj].start = ARRAY_NOTATION_START (ii_tree);
-	      (*node)[ii][jj].length =
-		fold_build1 (CONVERT_EXPR, integer_type_node,
-			     ARRAY_NOTATION_LENGTH (ii_tree));
-	      (*node)[ii][jj].stride =
-		fold_build1 (CONVERT_EXPR, integer_type_node,
-			     ARRAY_NOTATION_STRIDE (ii_tree));
-	    }
+	  {
+	    tree ii_tree = array_exprs[ii][jj];
+	    (*node)[ii][jj].is_vector = true;
+	    (*node)[ii][jj].value = ARRAY_NOTATION_ARRAY (ii_tree);
+	    (*node)[ii][jj].start = ARRAY_NOTATION_START (ii_tree);
+	    (*node)[ii][jj].length =
+	      fold_build1 (CONVERT_EXPR, integer_type_node,
+			   ARRAY_NOTATION_LENGTH (ii_tree));
+	    (*node)[ii][jj].stride =
+	      fold_build1 (CONVERT_EXPR, integer_type_node,
+			   ARRAY_NOTATION_STRIDE (ii_tree));
+	  }
 }
 
 /* Replaces all the __sec_implicit_arg functions in LIST with the induction
@@ -637,16 +637,15 @@ fix_sec_implicit_args (location_t loc, vec <tree, va_gc> *list,
   vec <tree, va_gc> *array_operand = NULL;
   for (size_t ii = 0; ii < vec_safe_length (list); ii++)
     if (TREE_CODE ((*list)[ii]) == CALL_EXPR
-	&& TREE_CODE (CALL_EXPR_FN ((*list)[ii])) == ADDR_EXPR
 	&& is_sec_implicit_index_fn (CALL_EXPR_FN ((*list)[ii])))
       {
 	int idx = extract_sec_implicit_index_arg (loc, (*list)[ii]);
-	if (idx < (int) rank && idx >= 0)
-	  vec_safe_push (array_operand, an_loop_info[idx].var);
-	else if (idx == -1)
+	if (idx < 0)
 	  /* In this case, the returning function would have emitted an
 	     error thus it is not necessary to do so again.  */
 	  return NULL;
+	else if (idx < (int) rank)
+	  vec_safe_push (array_operand, an_loop_info[idx].var);
 	else
 	  {
 	    error_at (loc, "__sec_implicit_index argument %d must be "
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index d6a500e..c7846ce 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -11053,24 +11053,6 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
 	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
 	      return error_mark_node;
 	    }
-	  if (TREE_CODE (array_type) == ARRAY_TYPE)
-	    {
-	      tree subtype = TREE_TYPE (array_type);
-	      while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
-		{
-		  /* Now this could be a function pointer.  Find them and
-		     give out an error.  */
-		  subtype = TREE_TYPE (subtype);
-		  if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
-		    {
-		      error_at (loc, "array notations cannot be used with "
-				"function pointer arrays");
-		      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
-						 NULL);
-		      return error_mark_node;
-		    }
-		}
-	    }
 	  array_type_domain = TYPE_DOMAIN (array_type);
 
 	  if (!array_type_domain)
@@ -11114,27 +11096,6 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
 	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
 	      return error_mark_node;
 	    }
-	  if (TREE_CODE (array_type) == ARRAY_TYPE
-	      || TREE_CODE (array_type) == POINTER_TYPE)
-	    {
-	      tree subtype = TREE_TYPE (array_type);
-	      while (subtype
-		     && (TREE_CODE (subtype) == POINTER_TYPE
-			 || TREE_CODE (subtype) == ARRAY_TYPE))
-		{
-		  /* Now this could be a function pointer.  Find them and
-		     give out an error.  */
-		  subtype = TREE_TYPE (subtype);
-		  if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
-		    {
-		      error_at (loc, "array notations cannot be used with "
-				"function pointer arrays");
-		      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
-						 NULL);
-		      return error_mark_node;
-		    }
-		}
-	    }
 	  c_parser_consume_token (parser); /* consume the ':' */
 	  end_index = c_parser_expression (parser).value;
 	  if (!end_index || end_index == error_mark_node)
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 6817bfc..425ef9b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -216,7 +216,6 @@ static void add_candidates (tree, tree, const vec<tree, va_gc> *, tree, tree,
 			    bool, tree, tree, int, struct z_candidate **,
 			    tsubst_flags_t);
 static conversion *merge_conversion_sequences (conversion *, conversion *);
-static bool magic_varargs_p (tree);
 static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
 
 /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
@@ -5857,16 +5856,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 	  else if (t->kind == ck_identity)
 	    break;
 	}
-
-      if (flag_enable_cilkplus
-	  && (contains_array_notation_expr (expr)
-	      || contains_array_notation_expr (fn)))
-	/* If we are using array notations, we fix them up at a later stage
-	   and we will do these checks then.  */
-	;
-      else if (permerror (loc, "invalid conversion from %qT to %qT",
-			  TREE_TYPE (expr), totype)
-	       && fn)
+       if (permerror (loc, "invalid conversion from %qT to %qT",
+                    TREE_TYPE (expr), totype)
+	   && fn)
 	inform (DECL_SOURCE_LOCATION (fn),
 		"initializing argument %P of %qD", argnum, fn);
 
@@ -6515,9 +6507,12 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
    which no conversions at all should be done.  This is true for some
    builtins which don't act like normal functions.  */
 
-static bool
+bool
 magic_varargs_p (tree fn)
 {
+  if (flag_enable_cilkplus && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE)
+    return true;
+
   if (DECL_BUILT_IN (fn))
     switch (DECL_FUNCTION_CODE (fn))
       {
@@ -6895,21 +6890,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 		       "  (you can disable this with -fno-deduce-init-list)");
 	    }
 	}
+      val = convert_like_with_context (conv, arg, fn, i - is_method,
+				       conversion_warning
+				       ? complain
+				       : complain & (~tf_warning));
 
-      /* If the function call is builtin array notation function then no need
-	 to do any type conversion.  */
-      if (flag_enable_cilkplus
-	  && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE)
-	val = arg;
-      else
-	{
-	  val = convert_like_with_context (conv, arg, fn, i - is_method,
-					   conversion_warning
-					   ? complain
-					   : complain & (~tf_warning));
-
-	  val = convert_for_arg_passing (type, val, complain);
-	}
+      val = convert_for_arg_passing (type, val, complain);
+	
       if (val == error_mark_node)
         return error_mark_node;
       else
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index 491da0f..b4fada4 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -59,7 +59,6 @@
 #include "diagnostic.h"
 #include "tree-iterator.h"
 #include "vec.h"
-#include "gimple.h"
 
 /* Creates a FOR_STMT with INIT, COND, INCR and BODY as the initializer,
    condition, increment expression and the loop-body, respectively.  */
@@ -82,17 +81,12 @@ create_an_loop (tree init, tree cond, tree incr, tree body)
    a variable to make it loop invariant for array notations.  */
 
 static inline void
-make_triplet_val_inv (location_t loc, tree *value, tsubst_flags_t cry)
+make_triplet_val_inv (tree *value)
 {
-  tree var;
   if (TREE_CODE (*value) != INTEGER_CST
       && TREE_CODE (*value) != PARM_DECL
       && TREE_CODE (*value) != VAR_DECL)
-    {
-      var = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
-      finish_expr_stmt (build_x_modify_expr (loc, var, NOP_EXPR, *value, cry));
-      *value = var;
-    }
+    *value = get_temp_regvar (ptrdiff_type_node, *value);
 }
 
 /* Returns a vector of size RANK that contains an ARRAY_REF.  This vector is
@@ -140,9 +134,9 @@ create_array_refs (location_t loc, vec<vec<an_parts> > an_info,
 		   integer.  The reason why we pick an integer
 		   instead of something like size_t is because the stride
 		   and length can be + or -.  */
-		st = build_c_cast (loc, integer_type_node, start);
-		str = build_c_cast (loc, integer_type_node, stride);
-		v = build_c_cast (loc, integer_type_node, var);
+		st = build_c_cast (loc, ptrdiff_type_node, start);
+		str = build_c_cast (loc, ptrdiff_type_node, stride);
+		v = build_c_cast (loc, ptrdiff_type_node, var);
 	      }
 	    else
 	      {
@@ -192,7 +186,7 @@ replace_invariant_exprs (tree *node)
 {
   size_t ix = 0;
   tree node_list = NULL_TREE;
-  tree t = NULL_TREE, new_var = NULL_TREE, new_node; 
+  tree t = NULL_TREE, new_var = NULL_TREE;
   struct inv_list data;
 
   data.list_values = NULL;
@@ -204,17 +198,11 @@ replace_invariant_exprs (tree *node)
     {
       node_list = push_stmt_list ();
       for (ix = 0; vec_safe_iterate (data.list_values, ix, &t); ix++)
-	{
-	  if (processing_template_decl || !TREE_TYPE (t))
-	    new_var = build_min_nt_loc (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
-				       	NULL_TREE);
-	  else
-	    new_var = build_decl (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
-				  TREE_TYPE (t));
-	  gcc_assert (new_var != NULL_TREE && new_var != error_mark_node);
-	  new_node = build_x_modify_expr (EXPR_LOCATION (t), new_var, NOP_EXPR,
-					  t, tf_warning_or_error);
-	  finish_expr_stmt (new_node);
+	{ 
+	  /* Sometimes, it type-casts certain functions to void. Unwrap it.  */
+	  if (VOID_TYPE_P (TREE_TYPE (t)) && TREE_CODE (t) == CONVERT_EXPR)
+	    t = TREE_OPERAND (t, 0);
+	  new_var = get_temp_regvar (TREE_TYPE (t), t); 
 	  vec_safe_push (data.replacement, new_var);
 	}
       cp_walk_tree (node, replace_inv_trees, (void *) &data, NULL);
@@ -235,7 +223,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
   tree new_var_type = NULL_TREE, func_parm, new_yes_expr, new_no_expr;
   tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list;
   tree new_yes_list, new_cond_expr, new_expr = NULL_TREE; 
-  tree new_var_init = NULL_TREE, new_exp_init = NULL_TREE;
   vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
   size_t list_size = 0, rank = 0, ii = 0;
   tree  body, an_init, loop_with_init = alloc_stmt_list ();
@@ -305,7 +292,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
-      new_var_type = integer_type_node;
+      new_var_type = boolean_type_node;
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
@@ -334,24 +321,30 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
     if (TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF)
       {
 	tree anode = (*array_list)[ii];
-	make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode),
-			      tf_warning_or_error);
-	make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode),
-			      tf_warning_or_error);
-	make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode),
-			      tf_warning_or_error);
+	make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+	make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+	make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
       }
   cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
   for (ii = 0; ii < rank; ii++)
     {
-      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-				  TREE_TYPE (an_info[0][ii].start));
-      an_loop_info[ii].ind_init = build_x_modify_expr
-	(location, an_loop_info[ii].var, NOP_EXPR, 
-	 build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
-	 tf_warning_or_error);
+      tree typ = ptrdiff_type_node;
+
+      /* In this place, we are using get_temp_regvar instead of 
+	 create_temporary_var if an_type is SEC_REDUCE_MAX/MIN_IND because
+	 the array_ind_value depends on this value being initalized to 0.  */
+      if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+	  || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND) 
+	an_loop_info[ii].var = get_temp_regvar (typ, build_zero_cst (typ));
+      else
+	{
+	  an_loop_info[ii].var = create_temporary_var (typ);
+	  add_decl_expr (an_loop_info[ii].var);
+	}
+      an_loop_info[ii].ind_init = 
+	build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
+			     build_zero_cst (typ), tf_warning_or_error);
     }
-  
   array_operand = create_array_refs (location, an_info, an_loop_info,
 				      list_size, rank);
   replace_array_notations (&func_parm, true, array_list, array_operand);
@@ -360,26 +353,9 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
     TREE_TYPE (func_parm) = TREE_TYPE ((*array_list)[0]);
   
   create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
-  if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
-    {
-      if (processing_template_decl)
-	*new_var = build_decl (location, VAR_DECL, NULL_TREE, new_var_type);
-      else
-	*new_var = create_tmp_var (new_var_type, NULL);
-    }
-  else
-    /* We do not require a new variable for mutating.  The "identity value"
-       itself is the variable.  */
-    *new_var = NULL_TREE;
-  
   if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
-      || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
-    {
-      array_ind_value = create_tmp_var (TREE_TYPE (func_parm), NULL);
-      gcc_assert (array_ind_value && (array_ind_value != error_mark_node));
-      DECL_INITIAL (array_ind_value) = NULL_TREE;
-      pushdecl (array_ind_value);
-    }
+      || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND) 
+    array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm);
 
   array_op0 = (*array_operand)[0];
   switch (an_type)
@@ -394,35 +370,36 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
-      code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
-	: NE_EXPR;
+      code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
+	: NE_EXPR);
       init = build_zero_cst (new_var_type);
       cond_init = build_one_cst (new_var_type);
       comp_node = build_zero_cst (TREE_TYPE (func_parm));
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
-      code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
-	: EQ_EXPR;
+      code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
+	: EQ_EXPR);
       init = build_one_cst (new_var_type);
       cond_init = build_zero_cst (new_var_type);
       comp_node = build_zero_cst (TREE_TYPE (func_parm));
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
       code = MAX_EXPR;
-      init = TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
-	: func_parm;
+      init = (TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
+	: func_parm);
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
       code = MIN_EXPR;
-      init = TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
-	: func_parm;
+      init = (TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
+	: func_parm);
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
-      code = an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
-	: GE_EXPR;
+      code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
+	: GE_EXPR);
       init = an_loop_info[0].var;
+      break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE:
       init = identity_value;
       break;
@@ -433,9 +410,11 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
       gcc_unreachable ();
     }
 
-  if (init)
-    new_var_init = build_x_modify_expr (location, *new_var, NOP_EXPR, init,
-					tf_warning_or_error);
+  if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+    *new_var = get_temp_regvar (new_var_type, init);
+  else
+    *new_var = NULL_TREE;
+
   switch (an_type)
     {
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
@@ -470,8 +449,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
       break;
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
     case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
-      new_exp_init = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
-					  func_parm, tf_warning_or_error);
       new_yes_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
 					  func_parm, tf_warning_or_error);
       new_no_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
@@ -521,21 +498,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
     default:
       gcc_unreachable ();
     }
-  
-  /* The reason we are putting initial variable twice is because the
-     new exp init below depends on this value being initialized.  */
-  for (ii = 0; ii < rank; ii++)
-    finish_expr_stmt (an_loop_info[ii].ind_init);
- 
-  if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
-    finish_expr_stmt (new_var_init);
-
-  if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
-      || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
-    finish_expr_stmt (new_exp_init);
-
   an_init = pop_stmt_list (an_init);
-  append_to_statement_list_force (an_init, &loop_with_init);
+  append_to_statement_list (an_init, &loop_with_init);
   body = new_expr;
 
   for (ii = 0; ii < rank; ii++)
@@ -545,7 +509,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
 		      an_loop_info[ii].incr, body);
       body = pop_stmt_list (new_loop);
     }
-  append_to_statement_list_force (body, &loop_with_init);
+  append_to_statement_list (body, &loop_with_init);
 
   an_info.release ();
   an_loop_info.release ();
@@ -634,10 +598,7 @@ expand_an_in_modify_expr (location_t location, tree lhs,
 	  return an_init;
 	}
       else
-	{
-	  pop_stmt_list (an_init);
-	  return NULL_TREE;
-	}
+	gcc_unreachable ();
     }
 
   /* If for some reason location is not set, then find if LHS or RHS has
@@ -659,8 +620,6 @@ expand_an_in_modify_expr (location_t location, tree lhs,
     
   if (lhs_rank == 0 && rhs_rank != 0)
     {
-      if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (rhs))
-	location = EXPR_LOCATION (rhs);
       error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs);
       return error_mark_node;
     }
@@ -675,17 +634,17 @@ expand_an_in_modify_expr (location_t location, tree lhs,
   for (ii = 0; ii < lhs_list_size; ii++)
     {
       tree anode = (*lhs_list)[ii];
-      make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain);
-      make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain);
-      make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain);
+      make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+      make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+      make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
     }
   for (ii = 0; ii < rhs_list_size; ii++)
     if ((*rhs_list)[ii] && TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
       {
 	tree aa = (*rhs_list)[ii];
-	make_triplet_val_inv (location, &ARRAY_NOTATION_START (aa), complain);
-	make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (aa), complain);
-	make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (aa), complain);
+	make_triplet_val_inv (&ARRAY_NOTATION_START (aa));
+	make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (aa));
+	make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (aa));
       }
   lhs_an_loop_info.safe_grow_cleared (lhs_rank);
   
@@ -705,31 +664,29 @@ expand_an_in_modify_expr (location_t location, tree lhs,
       pop_stmt_list (an_init);
       return error_mark_node;
     }
-  tree rhs_len = (rhs_list_size > 0 && rhs_rank > 0) ?
-    rhs_an_info[0][0].length : NULL_TREE;
-  tree lhs_len = (lhs_list_size > 0 && lhs_rank > 0) ?
-    lhs_an_info[0][0].length : NULL_TREE;
+  tree rhs_len = ((rhs_list_size > 0 && rhs_rank > 0) ?
+    rhs_an_info[0][0].length : NULL_TREE);
+  tree lhs_len = ((lhs_list_size > 0 && lhs_rank > 0) ?
+    lhs_an_info[0][0].length : NULL_TREE);
   if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
       && TREE_CODE (lhs_len) == INTEGER_CST && rhs_len
-      && TREE_CODE (rhs_len) == INTEGER_CST)
-    {
-      HOST_WIDE_INT l_length = int_cst_value (lhs_len);
-      HOST_WIDE_INT r_length = int_cst_value (rhs_len);
-      if (absu_hwi (l_length) != absu_hwi (r_length))
-	{
-	  error_at (location, "length mismatch between LHS and RHS");
-	  pop_stmt_list (an_init);
-	  return error_mark_node;
-	}
+      && TREE_CODE (rhs_len) == INTEGER_CST 
+      && !tree_int_cst_equal (rhs_len, lhs_len))
+    { 
+      error_at (location, "length mismatch between LHS and RHS"); 
+      pop_stmt_list (an_init); 
+      return error_mark_node;
     }
-   for (ii = 0; ii < lhs_rank; ii++)
-    if (lhs_an_info[0][ii].start && TREE_TYPE (lhs_an_info[0][ii].start))
-      lhs_an_loop_info[ii].var =
-	build_decl (location, VAR_DECL, NULL_TREE,
-		    TREE_TYPE (lhs_an_info[0][ii].start));
-    else
-      lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-					     integer_type_node);
+   for (ii = 0; ii < lhs_rank; ii++) 
+     {
+       tree typ = ptrdiff_type_node; 
+       lhs_an_loop_info[ii].var = create_temporary_var (typ);
+       add_decl_expr (lhs_an_loop_info[ii].var);
+       lhs_an_loop_info[ii].ind_init = build_x_modify_expr 
+	 (location, lhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ), 
+	  complain);
+     }
+   
    if (rhs_list_size > 0)
      {
        rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
@@ -743,24 +700,15 @@ expand_an_in_modify_expr (location_t location, tree lhs,
   rhs_list = NULL;
   extract_array_notation_exprs (rhs, true, &rhs_list);
   rhs_list_size = vec_safe_length (rhs_list);    
-  
-  for (ii = 0; ii < lhs_rank; ii++)
-    if (lhs_an_info[0][ii].is_vector)
-      {
-	lhs_an_loop_info[ii].ind_init = build_x_modify_expr
-	  (location, lhs_an_loop_info[ii].var, NOP_EXPR,
-	   build_zero_cst (TREE_TYPE (lhs_an_loop_info[ii].var)), complain);
-      }
+
   for (ii = 0; ii < rhs_rank; ii++)
     {
-      /* When we have a polynomial, we assume that the indices are of type
-	 integer.  */
-      rhs_an_loop_info[ii].var =
-	build_decl (location, VAR_DECL, NULL_TREE,
-		    TREE_TYPE (rhs_an_info[0][ii].start));
+      tree typ = ptrdiff_type_node;
+      rhs_an_loop_info[ii].var = create_temporary_var (typ);
+      add_decl_expr (rhs_an_loop_info[ii].var);
       rhs_an_loop_info[ii].ind_init = build_x_modify_expr
-	(location, rhs_an_loop_info[ii].var, NOP_EXPR, 
-	 build_zero_cst (TREE_TYPE (rhs_an_loop_info[ii].var)), complain);
+	(location, rhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ), 
+	 complain);
     }
 
   if (lhs_rank)
@@ -809,12 +757,12 @@ expand_an_in_modify_expr (location_t location, tree lhs,
     else if (ii < lhs_rank && ii >= rhs_rank)
       cond_expr[ii] = lhs_an_loop_info[ii].cmp;
     else
-      /* No need to compare ii < rhs_rank && ii >= lhs_rank because valid Array
-	 notation expression cannot RHS's rank cannot be greater than LHS.  */
+      /* No need to compare ii < rhs_rank && ii >= lhs_rank because in a valid 
+	 Array notation expression, rank of RHS cannot be greater than LHS.  */
       gcc_unreachable ();
   
   an_init = pop_stmt_list (an_init);
-  append_to_statement_list_force (an_init, &loop_with_init);
+  append_to_statement_list (an_init, &loop_with_init);
   body = array_expr;
   for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
     {
@@ -824,17 +772,13 @@ expand_an_in_modify_expr (location_t location, tree lhs,
 
       if (lhs_rank)
 	{
-	  append_to_statement_list_force (lhs_an_loop_info[ii].ind_init,
-					  &init_list);
-	  append_to_statement_list_force (lhs_an_loop_info[ii].incr,
-					  &incr_list);
+	  append_to_statement_list (lhs_an_loop_info[ii].ind_init, &init_list);
+	  append_to_statement_list (lhs_an_loop_info[ii].incr, &incr_list);
 	}
       if (rhs_rank)
 	{
-	  append_to_statement_list_force (rhs_an_loop_info[ii].ind_init,
-					  &init_list);
-	  append_to_statement_list_force (rhs_an_loop_info[ii].incr,
-					  &incr_list);
+	  append_to_statement_list (rhs_an_loop_info[ii].ind_init, &init_list);
+	  append_to_statement_list (rhs_an_loop_info[ii].incr, &incr_list);
 	}
       create_an_loop (init_list, cond_expr[ii], incr_list, body);
       body = pop_stmt_list (new_loop);
@@ -867,7 +811,6 @@ cp_expand_cond_array_notations (tree orig_stmt)
   tree an_init, body, stmt = NULL_TREE;
   tree builtin_loop, new_var = NULL_TREE;
   tree loop_with_init = alloc_stmt_list ();
-  tsubst_flags_t complain = tf_warning_or_error;
   location_t location = UNKNOWN_LOCATION;
   vec<vec<an_parts> > an_info = vNULL;
   vec<an_loop_parts> an_loop_info = vNULL;
@@ -884,13 +827,17 @@ cp_expand_cond_array_notations (tree orig_stmt)
 	  || find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
 			&no_rank))
 	return error_mark_node;
-      if (cond_rank != 0 && cond_rank != yes_rank && yes_rank != 0)
+      /* If the condition has a zero rank, then handle array notations in body
+	 seperately.  */
+      if (cond_rank == 0)
+	return orig_stmt;
+      if (cond_rank != yes_rank && yes_rank != 0)
 	{
 	  error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
 		    " expression of parent if-statement");
 	  return error_mark_node;
 	}
-      else if (cond_rank != 0 && cond_rank != no_rank && no_rank != 0)
+      else if (cond_rank != no_rank && no_rank != 0)
 	{
 	  error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
 		    "expression of parent if-statement");
@@ -911,13 +858,17 @@ cp_expand_cond_array_notations (tree orig_stmt)
 	      && !find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
 			     &no_rank)))
 	return error_mark_node;
-      if (cond_rank != 0 && cond_rank != yes_rank && yes_rank != 0)
+
+      /* Same reasoning as for COND_EXPR.  */
+      if (cond_rank == 0)
+	return orig_stmt;
+      else if (cond_rank != yes_rank && yes_rank != 0)
 	{
 	  error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
 		    " expression of parent if-statement");
 	  return error_mark_node;
 	}
-      else if (cond_rank != 0 && cond_rank != no_rank && no_rank != 0)
+      else if (cond_rank != no_rank && no_rank != 0)
 	{
 	  error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
 		    "expression of parent if-statement");
@@ -949,11 +900,11 @@ cp_expand_cond_array_notations (tree orig_stmt)
 	      vec_safe_push (new_var_list, new_var);
 	      replace_array_notations (&orig_stmt, false, sub_list,
 				       new_var_list);
-	      append_to_statement_list_force (builtin_loop, &stmt);
+	      append_to_statement_list (builtin_loop, &stmt);
 	    }
 	}
     }
-  append_to_statement_list_force (orig_stmt, &stmt);
+  append_to_statement_list (orig_stmt, &stmt);
   rank = 0;
   array_list = NULL;
   if (!find_rank (EXPR_LOCATION (stmt), stmt, stmt, true, &rank))
@@ -977,37 +928,28 @@ cp_expand_cond_array_notations (tree orig_stmt)
   for (ii = 0; ii < list_size; ii++)
     {
       tree anode = (*array_list)[ii];
-      make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain);
-      make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain);
-      make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain);
+      make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
+      make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
+      make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
     }
   cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
-  for (ii = 0; ii < rank; ii++)
-      if (TREE_TYPE (an_info[0][ii].start)
-	  && TREE_CODE (TREE_TYPE (an_info[0][ii].start)) != TEMPLATE_TYPE_PARM)
-	{
-	  an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-					     TREE_TYPE (an_info[0][ii].start));
-	  an_loop_info[ii].ind_init = build_x_modify_expr
-	    (location, an_loop_info[ii].var, NOP_EXPR,
-	     build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
-	     tf_warning_or_error);
-	}
-      else
-	{
-	  an_loop_info[ii].var = build_min_nt_loc (location, VAR_DECL,
-						   NULL_TREE, NULL_TREE);
-	  an_loop_info[ii].ind_init =
-	    build_x_modify_expr (location, an_loop_info[ii].var, NOP_EXPR,
-				 integer_zero_node, tf_warning_or_error);
-	}
+
+  for (ii = 0; ii < rank; ii++) 
+    {
+      tree typ = ptrdiff_type_node;
+      an_loop_info[ii].var = create_temporary_var (typ);
+      add_decl_expr (an_loop_info[ii].var);
+      an_loop_info[ii].ind_init =
+	build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
+			     build_zero_cst (typ), tf_warning_or_error);
+    }
   array_operand = create_array_refs (location, an_info, an_loop_info,
 				     list_size, rank);
   replace_array_notations (&stmt, true, array_list, array_operand);
   create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
   
   an_init = pop_stmt_list (an_init);
-  append_to_statement_list_force (an_init, &loop_with_init);
+  append_to_statement_list (an_init, &loop_with_init);
   body = stmt;
 
   for (ii = 0; ii < rank; ii++)
@@ -1017,7 +959,7 @@ cp_expand_cond_array_notations (tree orig_stmt)
 		      an_loop_info[ii].incr, body);
       body = pop_stmt_list (new_loop);
     }
-  append_to_statement_list_force (body, &loop_with_init);
+  append_to_statement_list (body, &loop_with_init);
 
   an_info.release ();
   an_loop_info.release ();
@@ -1062,14 +1004,14 @@ expand_unary_array_notation_exprs (tree orig_stmt)
 	  {
 	    vec<tree, va_gc> *sub_list = NULL, *new_var_list = NULL;
 	    stmt = alloc_stmt_list ();
-	    append_to_statement_list_force (builtin_loop, &stmt);
+	    append_to_statement_list (builtin_loop, &stmt);
 	    vec_safe_push (sub_list, list_node);
 	    vec_safe_push (new_var_list, new_var);
 	    replace_array_notations (&orig_stmt, false, sub_list, new_var_list);
 	  }	
       }
   if (stmt != NULL_TREE)
-    append_to_statement_list_force (finish_expr_stmt (orig_stmt), &stmt);
+    append_to_statement_list (finish_expr_stmt (orig_stmt), &stmt);
   else
     stmt = orig_stmt;
   rank = 0;
@@ -1089,22 +1031,19 @@ expand_unary_array_notation_exprs (tree orig_stmt)
   for (ii = 0; ii < list_size; ii++)
     {
       tree array_node = (*array_list)[ii];
-      make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node),
-			    tf_warning_or_error);
-      make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node),
-			    tf_warning_or_error);
-      make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node),
-			    tf_warning_or_error);
+      make_triplet_val_inv (&ARRAY_NOTATION_START (array_node));
+      make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (array_node));
+      make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (array_node));
     }
   cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
   
   for (ii = 0; ii < rank; ii++)
     {
-      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-				  TREE_TYPE (an_info[0][ii].start));
+      tree typ = ptrdiff_type_node;
+      an_loop_info[ii].var = create_temporary_var (typ);
+      add_decl_expr (an_loop_info[ii].var);
       an_loop_info[ii].ind_init = build_x_modify_expr
-	(location, an_loop_info[ii].var, NOP_EXPR, 
-	 build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
+	(location, an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ), 
 	 tf_warning_or_error);
     }
   array_operand = create_array_refs (location, an_info, an_loop_info,
@@ -1113,7 +1052,7 @@ expand_unary_array_notation_exprs (tree orig_stmt)
   create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
   
   an_init = pop_stmt_list (an_init);
-  append_to_statement_list_force (an_init, &loop_with_init);
+  append_to_statement_list (an_init, &loop_with_init);
   body = stmt;
   
   for (ii = 0; ii < rank; ii++)
@@ -1123,7 +1062,7 @@ expand_unary_array_notation_exprs (tree orig_stmt)
 		      an_loop_info[ii].incr, body);
       body = pop_stmt_list (new_loop);
     }
-  append_to_statement_list_force (body, &loop_with_init);
+  append_to_statement_list (body, &loop_with_init);
 
   an_info.release ();
   an_loop_info.release ();
@@ -1139,21 +1078,35 @@ static tree
 expand_return_expr (tree expr)
 {
   tree new_mod_list, new_var, new_mod, retval_expr;
-
+  size_t rank  = 0;
+  location_t loc = EXPR_LOCATION (expr);
   if (TREE_CODE (expr) != RETURN_EXPR)
     return expr;
+      
+  if (!find_rank (loc, expr, expr, false, &rank))
+    return error_mark_node;
 
-  location_t loc = EXPR_LOCATION (expr);
-  new_mod_list = alloc_stmt_list ();
+  /* If the return expression contains array notations, then flag it as
+     error.  */
+  if (rank >= 1)
+    {
+      error_at (loc, "array notation expression cannot be used as a return "
+		"value");
+      return error_mark_node;
+    }
+  
+  new_mod_list = push_stmt_list ();
   retval_expr = TREE_OPERAND (expr, 0);
-  new_var = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE (retval_expr));
+  new_var = create_temporary_var (TREE_TYPE (retval_expr));
+  add_decl_expr (new_var);
   new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR,
-					 TREE_OPERAND (retval_expr, 1),
-					 tf_warning_or_error);
+				      TREE_OPERAND (retval_expr, 1),
+				      tf_warning_or_error);
   TREE_OPERAND (retval_expr, 1) = new_var;
   TREE_OPERAND (expr, 0) = retval_expr;
-  append_to_statement_list_force (new_mod, &new_mod_list);
-  append_to_statement_list_force (expr, &new_mod_list);
+  add_stmt (new_mod);
+  add_stmt (expr);
+  new_mod_list = pop_stmt_list (new_mod_list);
   return new_mod_list;
 }
 
@@ -1290,19 +1243,21 @@ expand_array_notation_exprs (tree t)
       else
 	t = expand_array_notation_exprs (t);
       return t;
-
-    case SWITCH_EXPR:
-      t = cp_expand_cond_array_notations (t);
-      if (TREE_CODE (t) == SWITCH_EXPR)
-	SWITCH_BODY (t) = expand_array_notation_exprs (SWITCH_BODY (t));
-      else
-	t = expand_array_notation_exprs (t);
-      return t;
-    case FOR_STMT:      
+    case FOR_STMT:
+      if (contains_array_notation_expr (FOR_COND (t)))
+	{
+	  error_at (EXPR_LOCATION (FOR_COND (t)),
+		    "array notation cannot be used in a condition for "
+		    "a for-loop");
+	  return error_mark_node;
+	}
       /* FIXME: Add a check for CILK_FOR_STMT here when we add Cilk tasking 
 	 keywords.  */
       if (TREE_CODE (t) == FOR_STMT)
-	FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
+	{ 
+	  FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
+	  FOR_EXPR (t) = expand_array_notation_exprs (FOR_EXPR (t));
+	}
       else
 	t = expand_array_notation_exprs (t);
       return t;
@@ -1322,44 +1277,39 @@ expand_array_notation_exprs (tree t)
 	t = expand_array_notation_exprs (t);
       return t;
     case SWITCH_STMT:
-      t = cp_expand_cond_array_notations (t);
-      /* If the above function added some extra instructions above the original
-	 switch statement, then we can't assume it is still SWITCH_STMT so we
-	 have to check again.  */
-      if (TREE_CODE (t) == SWITCH_STMT)
+      if (contains_array_notation_expr (SWITCH_STMT_COND (t)))
 	{
-	  if (SWITCH_STMT_BODY (t))
-	    SWITCH_STMT_BODY (t) =
-	      expand_array_notation_exprs (SWITCH_STMT_BODY (t));
+	  error_at (EXPR_LOCATION (SWITCH_STMT_COND (t)),
+		    "array notation cannot be used as a condition for "
+		    "switch statement");
+	  return error_mark_node;
 	}
-      else
-	t = expand_array_notation_exprs (t);
+      if (SWITCH_STMT_BODY (t))
+	SWITCH_STMT_BODY (t) =
+	  expand_array_notation_exprs (SWITCH_STMT_BODY (t));
       return t;
     case WHILE_STMT:
-      t = cp_expand_cond_array_notations (t);
-      /* If the above function added some extra instructions above the original
-	 while statement, then we can't assume it is still WHILE_STMTso we
-	 have to check again.  */
-      if (TREE_CODE (t) == WHILE_STMT)
+      if (contains_array_notation_expr (WHILE_COND (t)))
 	{
-	  if (WHILE_BODY (t))
-	    WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
+	  if (EXPR_LOCATION (WHILE_COND (t)) != UNKNOWN_LOCATION)
+	    loc = EXPR_LOCATION (WHILE_COND (t));
+	  error_at (loc, "array notation cannot be used as a condition for "
+		    "while statement");
+	  return error_mark_node;
 	}
-      else
-	t = expand_array_notation_exprs (t);
+      if (WHILE_BODY (t))
+	WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
       return t;
     case DO_STMT:
-      t = cp_expand_cond_array_notations (t);
-      /* If the above function added some extra instructions above the original
-	 do-while statement, then we can't assume it is still DO_STMT so we
-	 have to check again.  */
-      if (TREE_CODE (t) == DO_STMT)
-	{      
-	  if (DO_BODY (t))
-	    DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
+      if (contains_array_notation_expr (DO_COND (t)))
+	{
+	  error_at (EXPR_LOCATION (DO_COND (t)),
+		    "array notation cannot be used as a condition for a "
+		    "do-while statement");
+	  return error_mark_node;
 	}
-      else
-	t = expand_array_notation_exprs (t);
+      if (DO_BODY (t))
+	DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
       return t;
     default:
       if (is_expr)
@@ -1380,57 +1330,64 @@ expand_array_notation_exprs (tree t)
   return t;
 }
 
-/* Given the base of an array (ARRAY), the START_INDEX, the number of elements
-   to be accessed (LENGTH) and the STRIDE, construct an ARRAY_NOTATION_REF tree
-   of type TYPE and return it.  Restrictions on START_INDEX, LENGTH and STRIDE 
-   are the same as that of index field passed into ARRAY_REF.  The only
-   additional restriction is that, unlike index in ARRAY_REF, stride, length
-   and start_index cannot contain array notations.  */
+/* Given the base of an array (ARRAY), the START (start_index), the number of 
+   elements to be accessed (LENGTH) and the STRIDE, construct an 
+   ARRAY_NOTATION_REF tree of type TYPE and return it.  Restrictions on START, 
+   LENGTH and STRIDE are the same as that of index field passed into ARRAY_REF. 
+   The only additional restriction is that, unlike index in ARRAY_REF, stride, 
+   length and start_index cannot contain array notations.  */
 
 tree
-build_array_notation_ref (location_t loc, tree array, tree start_index,
-			  tree length, tree stride, tree type)
+build_array_notation_ref (location_t loc, tree array, tree start, tree length, 
+			  tree stride, tree type)
 {
   tree array_ntn_expr = NULL_TREE;
-  
-  /* When dealing with templates, do the type checking at a later time.  */
-  if (processing_template_decl || !type)
-    {
-      if (!type && TREE_TYPE (array))
-	type = TREE_TYPE (array);
-      array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array,
-					 start_index, length, stride, type,
-					 NULL_TREE);
-      TREE_TYPE (array_ntn_expr) = type;
-    }
-  if (!stride)
-    {
-      if (TREE_CONSTANT (start_index) && TREE_CONSTANT (length)
-	  && TREE_CODE (start_index) != VAR_DECL
-	  && TREE_CODE (length) != VAR_DECL
-	  && tree_int_cst_lt (length, start_index))
-	stride = build_int_cst (TREE_TYPE (start_index), -1);
-      else
-	stride = build_int_cst (TREE_TYPE (start_index), 1);
-    }
 
-  if (!cilkplus_an_triplet_types_ok_p (loc, start_index, length, stride, type))
-    return error_mark_node;
-
-  if (!processing_template_decl)
+  /* If we enter the then-case of the if-statement below, we have hit a case 
+     like this: ARRAY [:].  */
+  if (!start && !length)
     {
-      array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, NULL_TREE,
-			       NULL_TREE, NULL_TREE, NULL_TREE);
-      ARRAY_NOTATION_ARRAY (array_ntn_expr) = array;
-      ARRAY_NOTATION_START (array_ntn_expr) = start_index;
-      ARRAY_NOTATION_LENGTH (array_ntn_expr) = length;
-      ARRAY_NOTATION_STRIDE (array_ntn_expr) = stride;
-      if (type && (TREE_CODE (type) == ARRAY_TYPE
-		   || TREE_CODE (type) == POINTER_TYPE))
-	TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
-      else
-	TREE_TYPE (array_ntn_expr) = type;
+      if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == POINTER_TYPE)
+	{
+	  error_at (loc, "start-index and length fields necessary for "
+		    "using array notation in pointers or records");
+	  return error_mark_node;
+	}
+      tree domain = TYPE_DOMAIN (type);
+      if (!domain)
+	{
+	  error_at (loc, "start-index and length fields necessary for "
+		    "using array notation with array of unknown bound");
+	  return error_mark_node;
+	}
+      start = cp_fold_convert (ptrdiff_type_node, TYPE_MINVAL (domain));
+      length = size_binop (PLUS_EXPR, TYPE_MAXVAL (domain), size_one_node);
+      length = cp_fold_convert (ptrdiff_type_node, length);
     }
+    
+  if (!stride) 
+    stride = build_one_cst (ptrdiff_type_node);
+  
+  /* When dealing with templates, triplet type-checking will be done in pt.c 
+     after type substitution.  */
+  if (processing_template_decl 
+      && (type_dependent_expression_p (array) 
+	  || type_dependent_expression_p (length) 
+	  || type_dependent_expression_p (start) 
+	  || type_dependent_expression_p (stride))) 
+    array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array, start, 
+				       length, stride, NULL_TREE);
+  else 
+    { 
+      if (!cilkplus_an_triplet_types_ok_p (loc, start, length, stride, type))
+	return error_mark_node;
+      array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, array, start, 
+			       length, stride);
+    }
+  if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE)
+    TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
+  else
+    TREE_TYPE (array_ntn_expr) = type;
   SET_EXPR_LOCATION (array_ntn_expr, loc);
 
   return array_ntn_expr;
@@ -1462,20 +1419,9 @@ cilkplus_an_triplet_types_ok_p (location_t loc, tree start_index, tree length,
     }
   if (!TREE_CODE (type) == FUNCTION_TYPE)
     {
-      error_at (loc, "array notations cannot be used with function type");
+      error_at (loc, "array notation cannot be used with function type");
       return false;
     }
-  while (type && (TREE_CODE (type) == POINTER_TYPE
-		  || TREE_CODE (type) == ARRAY_TYPE))
-    {
-      type = TREE_TYPE (type);
-      if (type && TREE_CODE (type) == FUNCTION_TYPE)
-	{
-	  error_at (loc, "array notations cannot be used with function pointer"
-		    " arrays");
-	  return false;
-	}
-    }
   if (!find_rank (loc, start_index, start_index, false, &start_rank)
       || !find_rank (loc, length, length, false, &length_rank)
       || !find_rank (loc, stride, stride, false, &stride_rank))
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 38ef878..590d857 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1207,6 +1207,12 @@ cp_genericize (tree fndecl)
   if (DECL_CLONED_FUNCTION_P (fndecl))
     return;
 
+  /* Expand all the array notations here.  */
+  if (flag_enable_cilkplus 
+      && contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
+    DECL_SAVED_TREE (fndecl) = 
+      expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
+
   /* We do want to see every occurrence of the parms, so we can't just use
      walk_tree's hash functionality.  */
   cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 00ee450..a3438a8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4974,6 +4974,7 @@ extern bool pragma_java_exceptions;
 
 /* in call.c */
 extern bool check_dtor_name			(tree, tree);
+bool magic_varargs_p                            (tree);
 
 extern tree build_conditional_expr		(location_t, tree, tree, tree, 
                                                  tsubst_flags_t);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ec8ad46..ec8a5a9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6060,41 +6060,32 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
   return error_mark_node;
 }
 
-/* This function parses Cilk Plus array notations.  The starting index is
-   passed in INIT_INDEX and the array name is passed in ARRAY_VALUE.  If the
-   INIT_INDEX is NULL, then we have special case were the entire array is
-   accessed (e.g. A[:]).  The return value of this function is a tree node
-   called VALUE_TREE of type ARRAY_NOTATION_REF.  If some error occurred it
-   returns error_mark_node.  */
+/* This function parses Cilk Plus array notations.  If a normal array expr. is
+   parsed then the array index is passed back to the caller through *INIT_INDEX 
+   and the function returns a NULL_TREE.  If array notation expr. is parsed, 
+   then *INIT_INDEX is ignored by the caller and the function returns 
+   a tree of type ARRAY_NOTATION_REF.  If some error occurred it returns 
+   error_mark_node.  */
 
 static tree
-cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index,
+cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index,
 			  tree array_value)
 {
   cp_token *token = NULL;
-  tree start_index = NULL_TREE, length_index = NULL_TREE, stride = NULL_TREE;
-  tree value_tree, type, array_type, array_type_domain;
-  double_int x; 
-  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+  tree length_index, stride = NULL_TREE, value_tree, array_type;
+  bool saved_colon_corrects = parser->colon_corrects_to_scope_p;
 
   if (!array_value || array_value == error_mark_node)
     {
       cp_parser_skip_to_end_of_statement (parser);
       return error_mark_node;
     }
-  
-  if (processing_template_decl)
-    {
-      array_type = TREE_TYPE (array_value);
-      type = TREE_TYPE (array_type);
-    }
-  else
-    {
-      array_type = TREE_TYPE (array_value);
-      gcc_assert (array_type);
-      type = array_type;
-    }
+
+  array_type = TREE_TYPE (array_value);
+
+  parser->colon_corrects_to_scope_p = false;
   token = cp_lexer_peek_token (parser->lexer);
+  
   if (!token)
     {
       cp_parser_error (parser, "expected %<:%> or numeral");
@@ -6102,125 +6093,71 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index,
     }
   else if (token->type == CPP_COLON)
     {
-      if (!init_index)
+      /* Consume the ':'.  */
+      cp_lexer_consume_token (parser->lexer);
+      
+      /* If we are here, then we have a case like this A[:].  */
+      if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
 	{
-	  /* If we are here, then we have a case like this A[:].  */
-	  cp_lexer_consume_token (parser->lexer);
+	  cp_parser_error (parser, "expected %<]%>");
+	  cp_parser_skip_to_end_of_statement (parser);
+	  return error_mark_node;
+	}
+      *init_index = NULL_TREE;
+      stride = NULL_TREE;
+      length_index = NULL_TREE;
+    }
+  else
+    {
+      /* If we are here, then there are three valid possibilities:
+	 1. ARRAY [ EXP ]
+	 2. ARRAY [ EXP : EXP ]
+	 3. ARRAY [ EXP : EXP : EXP ]  */
 
-	  if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
-	    {
-	      cp_parser_error (parser, "expected %<]%>");
-	      cp_parser_skip_to_end_of_statement (parser);
-	      return error_mark_node;
-	    }
-	  if (TREE_CODE (array_type) == RECORD_TYPE
-	      || TREE_CODE (array_type) == POINTER_TYPE)
-	    {
-	      error_at (loc, "start-index and length fields necessary for "
-			"using array notations in pointers or records");
-	      cp_parser_skip_to_end_of_statement (parser);
-	      return error_mark_node;
-	    }
-	  if (TREE_CODE (array_type) == ARRAY_TYPE)
-	    {
-	      tree subtype = TREE_TYPE (array_type);
-	      while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
-		{
-		  /* This could be a function ptr.  If so, then emit error.  */
-		  subtype = TREE_TYPE (subtype);
-		  if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
-		    {
-		      error_at (loc, "array notations cannot be used with"
-				" function pointer arrays");
-		      cp_parser_skip_to_end_of_statement (parser);
-		      return error_mark_node;
-		    }
-		}
-	    }
-	  array_type_domain = TYPE_DOMAIN (array_type);
-	  if (!array_type_domain)
-	    {
-	      error_at (loc, "start-index and length fields necessary for "
-			"using array notations in dimensionless arrays");
-	      cp_parser_skip_to_end_of_statement (parser);
-	      return error_mark_node;
-	    }
-	  start_index = TYPE_MINVAL (array_type_domain);
-	  start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
-				     start_index);
-	  x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain));
-	  x.low++;
-	  length_index = double_int_to_tree (integer_type_node, x);
-	  length_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
-				      length_index);
-	  stride = build_int_cst (integer_type_node, 1);
-	  stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride);
-	}
-      else if (init_index != error_mark_node)
-	{
-	  /* If we hare here, then there are 2 possibilities:
-	     1. Array [ EXPR : EXPR ]
-	     2. Array [ EXPR : EXPR : EXPR ]
-	  */
-	  start_index = init_index;
-	  cp_lexer_consume_token (parser->lexer);
+      *init_index = cp_parser_expression (parser, false, NULL);
+	
+      if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
+	{  
+	  /* This indicates that we have a normal array expression.  */
+	  parser->colon_corrects_to_scope_p = saved_colon_corrects;
+	  return NULL_TREE;
+	}
+      
+      /* Consume the ':'.  */
+      cp_lexer_consume_token (parser->lexer);
 
-	  saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
-	   /* The ':' is used in array notation.  Thus compiler cannot do scope 
-	      correction automatically.  */
-	  parser->colon_corrects_to_scope_p = false;
-	  length_index = cp_parser_expression (parser, false, NULL);
-	  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
-	  if (!length_index || length_index == error_mark_node)
-	    cp_parser_skip_to_end_of_statement (parser);
-	 
-	  if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
+      if (!*init_index || *init_index == error_mark_node)
+	cp_parser_skip_to_end_of_statement (parser);
+
+      length_index = cp_parser_expression (parser, false, NULL);
+      if (!length_index || length_index == error_mark_node)
+	cp_parser_skip_to_end_of_statement (parser);
+      if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
+	{
+	  cp_lexer_consume_token (parser->lexer);
+	  stride = cp_parser_expression (parser, false, NULL);
+	  if (stride == error_mark_node)
 	    {
-	      cp_lexer_consume_token (parser->lexer);
-	      saved_colon_corrects_to_scope_p = 
-		parser->colon_corrects_to_scope_p;
-	      /* Disable correcting single colon correcting to scope.  */
-	      parser->colon_corrects_to_scope_p = false;
-	      stride = cp_parser_expression (parser, false, NULL);
-	      parser->colon_corrects_to_scope_p = 
-		saved_colon_corrects_to_scope_p;
-	      if (!stride || stride == error_mark_node)
-		{
-		  cp_parser_skip_to_end_of_statement (parser);
-		  if (cp_lexer_peek_token (parser->lexer)->type
-		      == CPP_CLOSE_SQUARE)
-		    cp_lexer_consume_token (parser->lexer);
-		}
+	      cp_parser_skip_to_end_of_statement (parser);
+	      if (cp_lexer_peek_token (parser->lexer)->type
+		  == CPP_CLOSE_SQUARE)
+		cp_lexer_consume_token (parser->lexer);
 	    }
-	  else
-	    stride = build_one_cst (integer_type_node);
-	}
-      else
-	{
-	  cp_parser_skip_to_end_of_statement (parser);
-	  return error_mark_node;
 	}
     }
-  
-  if (start_index == error_mark_node || length_index == error_mark_node
-      || stride == error_mark_node || !start_index || !length_index
-      || !stride)
+  parser->colon_corrects_to_scope_p = saved_colon_corrects;
+
+  if (*init_index == error_mark_node || length_index == error_mark_node
+      || stride == error_mark_node)
     {
       if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_SQUARE)
 	cp_lexer_consume_token (parser->lexer);
       return error_mark_node;
     }
   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
-  
-  /* We fold all 3 of the values to make things easier when we transform
-     them later.  */
-  start_index = fold (start_index);
-  length_index = fold (length_index);
-  stride = fold (stride);
-
-  value_tree = build_array_notation_ref (input_location, array_value,
-					 start_index, length_index, stride,
-					 type);
+
+  value_tree = build_array_notation_ref (loc, array_value, *init_index, 
+					 length_index, stride, array_type);
   return value_tree;
 }
 
@@ -6239,84 +6176,71 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
 					  bool for_offsetof,
 					  bool decltype_p)
 {
-  tree index;
+  tree index = NULL_TREE;
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Consume the `[' token.  */
   cp_lexer_consume_token (parser->lexer);
 
-  if (flag_enable_cilkplus
-      && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
-    /* If we are here, then we have something like this:
-       ARRAY[:]
-    */
-    postfix_expression = cp_parser_array_notation (loc, parser, NULL_TREE,
-						   postfix_expression);
+  /* Parse the index expression.  */
+  /* ??? For offsetof, there is a question of what to allow here.  If
+     offsetof is not being used in an integral constant expression context,
+     then we *could* get the right answer by computing the value at runtime.
+     If we are in an integral constant expression context, then we might
+     could accept any constant expression; hard to say without analysis.
+     Rather than open the barn door too wide right away, allow only integer
+     constant expressions here.  */
+  if (for_offsetof)
+    index = cp_parser_constant_expression (parser, false, NULL);
   else
     {
-      /* Here are have these options:
-	 1. ARRAY[EXPR]               -- This is the normal array call.
-	 2. ARRAY[EXPR : EXPR]        -- Array notation expr with default stride
-	 of 1.
-	 3. ARRAY[EXPR : EXPR : EXPR] -- Array Notation with userdefined stride.
-	 4. Array[Braced List]        -- This is handled by braced list.
-      */
-      
-      /* Parse the index expression.  */
-      /* ??? For offsetof, there is a question of what to allow here.  If
-	 offsetof is not being used in an integral constant expression context,
-	 then we *could* get the right answer by computing the value at runtime.
-	 If we are in an integral constant expression context, then we might
-	 could accept any constant expression; hard to say without analysis.
-	 Rather than open the barn door too wide right away, allow only integer
-	 constant expressions here.  */
-      if (for_offsetof)
-	index = cp_parser_constant_expression (parser, false, NULL);
-      else
+      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 	{
-	  bool saved_colon_corrects_to_scope_p = 
-	    parser->colon_corrects_to_scope_p;
-	  if (flag_enable_cilkplus)
-	    parser->colon_corrects_to_scope_p = false;
-	  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+	  bool expr_nonconst_p;
+	  maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+	  index = cp_parser_braced_list (parser, &expr_nonconst_p);
+	  bool saved_colon_corrects = parser->colon_corrects_to_scope_p;
+	  parser->colon_corrects_to_scope_p = false;
+	  if (flag_enable_cilkplus
+	      && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
 	    {
-	      bool expr_nonconst_p;
-	      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
-	      index = cp_parser_braced_list (parser, &expr_nonconst_p);
-	      if (flag_enable_cilkplus
-		  && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
-		{
-		  error_at (cp_lexer_peek_token (parser->lexer)->location,
-			    "braced list index is not allowed with array "
-			    "notations");
-		  index = error_mark_node;
-		}
+	      error_at (cp_lexer_peek_token (parser->lexer)->location,
+			"braced list index is not allowed with array "
+			"notation");
+	      cp_parser_skip_to_end_of_statement (parser);
+	      return error_mark_node;
 	    }
-	  else
-	    index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
-	  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
+	  parser->colon_corrects_to_scope_p = saved_colon_corrects;
 	}
-      if (flag_enable_cilkplus
-	  && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
-	postfix_expression = cp_parser_array_notation (loc, parser, index,
-						       postfix_expression);
-      else
+      else if (flag_enable_cilkplus)
 	{
-  	  /* Look for the closing `]'.  */
-	  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
-
-	  /* Build the ARRAY_REF.  */
-	  postfix_expression = grok_array_decl (loc, postfix_expression,
-						index, decltype_p);
-
-	  /* When not doing offsetof, array references are not permitted in
-	     constant-expressions.  */
-	  if (!for_offsetof
-	      && (cp_parser_non_integral_constant_expression (parser,
-							      NIC_ARRAY_REF)))
-	    postfix_expression = error_mark_node;
+	  /* Here are have these two options:
+	     ARRAY[EXP : EXP]        - Array notation expr with default
+	     stride of 1.
+	     ARRAY[EXP : EXP : EXP] - Array Notation with user-defined
+	     stride.  */
+	  tree an_exp = cp_parser_array_notation (loc, parser, &index, 
+						  postfix_expression);
+	  if (an_exp)
+	    return an_exp;
 	}
+      else
+	index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
     }
+
+  /* Look for the closing `]'.  */
+  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+
+  /* Build the ARRAY_REF.  */
+  postfix_expression = grok_array_decl (loc, postfix_expression,
+					index, decltype_p);
+
+  /* When not doing offsetof, array references are not permitted in
+     constant-expressions.  */
+  if (!for_offsetof
+      && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
+    postfix_expression = error_mark_node;
+
   return postfix_expression;
 }
 
@@ -9551,8 +9475,6 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
   /* Consume the `}'.  */
   cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 
-  if (flag_enable_cilkplus && contains_array_notation_expr (compound_stmt))
-    compound_stmt = expand_array_notation_exprs (compound_stmt);
   return compound_stmt;
 }
 
@@ -9745,14 +9667,6 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
 
 	    /* Now we're all done with the switch-statement.  */
 	    finish_switch_stmt (statement);
-	    if (flag_enable_cilkplus
-		&& contains_array_notation_expr (condition))
-	      {
-		error_at (EXPR_LOCATION (condition),
-			  "array notations cannot be used as a condition for "
-			  "switch statement");
-		statement = error_mark_node;
-	      }      
 	  }
 
 	return statement;
@@ -10310,12 +10224,6 @@ cp_parser_iteration_statement (cp_parser* parser)
 	parser->in_statement = in_statement;
 	/* We're done with the while-statement.  */
 	finish_while_stmt (statement);
-	if (flag_enable_cilkplus && contains_array_notation_expr (condition))
-	  {
-	    error_at (EXPR_LOCATION (condition), "array notations cannot be "
-		      "used as a condition for while statement");
-	    statement = error_mark_node;
-	  }
       }
       break;
 
@@ -10342,15 +10250,6 @@ cp_parser_iteration_statement (cp_parser* parser)
 	cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
 	/* Look for the `;'.  */
 	cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
-	if (flag_enable_cilkplus
-	    && contains_array_notation_expr (DO_COND (statement)))
-	  {
-	    error_at (EXPR_LOCATION (DO_COND (statement)),
-		      "array notations cannot be used as a condition for a "
-		      "do-while statement");
-	    statement = error_mark_node;
-	  }
-
       }
       break;
 
@@ -10369,17 +10268,8 @@ cp_parser_iteration_statement (cp_parser* parser)
 	cp_parser_already_scoped_statement (parser);
 	parser->in_statement = in_statement;
 
-	if (flag_enable_cilkplus
-	    && contains_array_notation_expr (FOR_COND (statement)))
-	  {
-	    error_at (EXPR_LOCATION (FOR_COND (statement)),
-		      "array notations cannot be used in a condition for a "
-		      "for-loop");
-	    statement = error_mark_node;
-	  }
-	else
-	  /* We're done with the for-statement.  */
-	  finish_for_stmt (statement);
+	/* We're done with the for-statement.  */
+	finish_for_stmt (statement);
       }
       break;
 
@@ -16952,54 +16842,30 @@ cp_parser_direct_declarator (cp_parser* parser,
 	  if (token->type != CPP_CLOSE_SQUARE)
 	    {
 	      bool non_constant_p;
-
-	      if (flag_enable_cilkplus
-		  && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+	      bounds
+		= cp_parser_constant_expression (parser,
+						 /*allow_non_constant=*/true,
+						 &non_constant_p);
+	      if (!non_constant_p)
+		/* OK */;
+	      else if (error_operand_p (bounds))
+		/* Already gave an error.  */;
+	      else if (!parser->in_function_body
+		       || current_binding_level->kind == sk_function_parms)
 		{
+		  /* Normally, the array bound must be an integral constant
+		     expression.  However, as an extension, we allow VLAs
+		     in function scopes as long as they aren't part of a
+		     parameter declaration.  */
+		  cp_parser_error (parser,
+				   "array bound is not an integer constant");
 		  bounds = error_mark_node;
-		  error_at (cp_lexer_peek_token (parser->lexer)->location,
-			    "array notations cannot be used in declaration");
-		  cp_lexer_consume_token (parser->lexer);
 		}
-	      else
+	      else if (processing_template_decl)
 		{
-		  bounds
-		    = cp_parser_constant_expression (parser,
-						     /*allow_non_constant=*/true,
-						     &non_constant_p);
-		  if (!non_constant_p)
-		    /* OK */;
-		  else if (error_operand_p (bounds))
-		    /* Already gave an error.  */;
-		  else if (!parser->in_function_body
-			   || current_binding_level->kind == sk_function_parms)
-		    {
-		      /* Normally, the array bound must be an integral constant
-			 expression.  However, as an extension, we allow VLAs
-			 in function scopes as long as they aren't part of a
-			 parameter declaration.  */
-		      cp_parser_error (parser,
-				       "array bound is not an integer constant");
-		      bounds = error_mark_node;
-		    }
-		  else if (processing_template_decl)
-		    {
-		      /* Remember this wasn't a constant-expression.  */
-		      bounds = build_nop (TREE_TYPE (bounds), bounds);
-		      TREE_SIDE_EFFECTS (bounds) = 1;
-		    }
-		  if (flag_enable_cilkplus
-		      && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
-		    {
-		      location_t loc =
-			cp_lexer_peek_token (parser->lexer)->location;
-		      while (cp_lexer_next_token_is_not (parser->lexer,
-							 CPP_CLOSE_SQUARE))
-			cp_lexer_consume_token (parser->lexer);
-		      error_at (loc, "array notations cannot be used in "
-			 	"declaration");
-		      bounds = error_mark_node; 
-		    }
+		  /* Remember this wasn't a constant-expression.  */
+		  bounds = build_nop (TREE_TYPE (bounds), bounds);
+		  TREE_SIDE_EFFECTS (bounds) = 1;
 		}
 	    }
 	  else
@@ -18370,11 +18236,6 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
   cp_parser_function_body (parser, in_function_try_block);
   if (check_body_p)
     check_constexpr_ctor_body (last, list);
-
-  /* Transform all array notations to the equivalent array refs and loop.  */
-  if (flag_enable_cilkplus && contains_array_notation_expr (body))
-    body = expand_array_notation_exprs (body);
-  
   /* Finish the function body.  */
   finish_function_body (body);
 
@@ -22354,12 +22215,6 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
 
   finish_lambda_scope ();
 
-  /* Expand all array notation expressions here.  */
-  if (flag_enable_cilkplus && current_function_decl
-      && contains_array_notation_expr (DECL_SAVED_TREE (current_function_decl)))
-    DECL_SAVED_TREE (current_function_decl) =
-      expand_array_notation_exprs (DECL_SAVED_TREE (current_function_decl));
-  
   /* Finish the function.  */
   fn = finish_function ((ctor_initializer_p ? 1 : 0) |
 			(inline_p ? 2 : 0));
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 667e37f..5dafdcd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15739,9 +15739,6 @@ type_unification_real (tree tparms,
       arg = args[ia];
       ++ia;
 
-      if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF)
-	return 1;
-
       if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
 			      flags, explain_p))
 	return 1;
@@ -19143,11 +19140,6 @@ instantiate_decl (tree d, int defer_ok,
       pointer_map_destroy (local_specializations);
       local_specializations = saved_local_specializations;
 
-      /* We expand all the array notation expressions here.  */
-      if (flag_enable_cilkplus
-	  && contains_array_notation_expr (DECL_SAVED_TREE (d)))
-	DECL_SAVED_TREE (d) = expand_array_notation_exprs (DECL_SAVED_TREE (d));
-      
       /* Finish the function.  */
       d = finish_function (0);
       expand_or_defer_fn (d);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0a460a4..87c1560 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -779,22 +779,6 @@ finish_return_stmt (tree expr)
   tree r;
   bool no_warning;
 
-  if (flag_enable_cilkplus && contains_array_notation_expr (expr))
-    {
-      size_t rank = 0;
-      
-      if (!find_rank (input_location, expr, expr, false, &rank))
-	return error_mark_node;
-
-      /* If the return expression contains array notations, then flag it as
-	 error.  */
-      if (rank >= 1)
-	{
-	  error_at (input_location, "array notation expression cannot be "
-		    "used as a return value");
-	  return error_mark_node;
-	}
-    }
   expr = check_return_expr (expr, &no_warning);
 
   if (flag_openmp && !check_omp_return ())
@@ -8089,7 +8073,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
 				       non_constant_p, overflow_p);
       break;
 
-    case ARRAY_NOTATION_REF:
     case ARRAY_REF:
       r = cxx_eval_array_reference (call, t, allow_non_constant, addr,
 				    non_constant_p, overflow_p);
@@ -8901,7 +8884,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
       want_rval = true;
       /* Fall through.  */
     case ARRAY_REF:
-    case ARRAY_NOTATION_REF:
     case ARRAY_RANGE_REF:
     case MEMBER_REF:
     case DOTSTAR_EXPR:
@@ -8912,6 +8894,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
 	  return false;
       return true;
 
+    case ARRAY_NOTATION_REF:
+      return false;
+
     case FMA_EXPR:
     case VEC_PERM_EXPR:
      for (i = 0; i < 3; ++i)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5b321ce..11592b4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3493,10 +3493,6 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
       params = &allocated;
     }
 
-  if (flag_enable_cilkplus
-      && is_cilkplus_reduce_builtin (fndecl) != BUILT_IN_NONE)
-    nargs = (*params)->length ();
-  else
     nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
 			       complain);
   if (nargs < 0)
@@ -3660,8 +3656,7 @@ convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
 	}
       else
 	{
-	  if (fndecl && DECL_BUILT_IN (fndecl)
-	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
+	  if (fndecl && magic_varargs_p (fndecl))
 	    /* Don't do ellipsis conversion for __built_in_constant_p
 	       as this will result in spurious errors for non-trivial
 	       types.  */
@@ -3956,15 +3951,8 @@ cp_build_binary_op (location_t location,
 	}
     }
 
-  if (flag_enable_cilkplus && contains_array_notation_expr (op0))
-    type0 = find_correct_array_notation_type (op0);
-  else
-    type0 = TREE_TYPE (op0);
-
-  if (flag_enable_cilkplus && contains_array_notation_expr (op1))
-    type1 = find_correct_array_notation_type (op1);
-  else
-    type1 = TREE_TYPE (op1);
+  type0 = TREE_TYPE (op0); 
+  type1 = TREE_TYPE (op1);
 
   /* The expression codes of the data types of the arguments tell us
      whether the arguments are integers, floating, pointers, etc.  */
@@ -5167,13 +5155,6 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
 
   gcc_assert (!identifier_p (arg) || !IDENTIFIER_OPNAME_P (arg));
 
-  if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF)
-    {
-      val = build_address (arg);
-      if (TREE_CODE (arg) == OFFSET_REF)
-	PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
-      return val;
-    }
   if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
       && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
     {
@@ -7852,13 +7833,6 @@ convert_for_assignment (tree type, tree rhs,
   tree rhstype;
   enum tree_code coder;
 
-  /* If we are dealing with built-in array notation function then we don't need
-     to convert them.  They will be broken up into modify exprs in future,
-     during which all these checks will be done.  */
-  if (flag_enable_cilkplus
-      && is_cilkplus_reduce_builtin (fndecl) != BUILT_IN_NONE)
-    return rhs;
-  
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
   if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
     rhs = TREE_OPERAND (rhs, 0);
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c
index 68c8859..4b54f4d 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/decl-ptr-colon.c
@@ -1,3 +1,4 @@
+/* { dg-do compile { target c } } */
 /* { dg-options "-fcilkplus" } */
 
 int main(void)
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c
index 69aaa52..690e89a 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/dimensionless-arrays.c
@@ -5,6 +5,6 @@ extern int *b;
 
 void foo()
 {
-  a[:] = 5;	// { dg-error "start-index and length fields necessary for using array notations in dimensionless arrays" }
-  b[:] = 5;    // { dg-error "start-index and length fields necessary for using array notations in pointers" }
+  a[:] = 5;	// { dg-error "start-index and length fields necessary for using array notation" }
+  b[:] = 5;    // { dg-error "start-index and length fields necessary for using" }
 }
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c
index 024a158..fa6d900 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/fn_ptr.c
@@ -1,3 +1,4 @@
+/* { dg-do compile } */
 /* { dg-options "-fcilkplus" } */
 
 typedef int (*foo)(int);
@@ -10,11 +11,11 @@ int main(void)
   foo ***func_array_ptr;
   int argc = 5;
 
-  array[:] =  func_array[:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
-  func_array[0:5](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
-  func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
-  array2[0:5][:] = func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
-  func_array_ptr[0:5][0:4][0:argc:2](argc); /* { dg-error "array notations cannot be used with function pointer arrays" } */
+  array[:] =  func_array[:](10); 
+  func_array[0:5](10); 
+  func_array2[0:5][:](10);
+  array2[0:5][:] = func_array2[0:5][:](10);
+  func_array_ptr[0:5][0:4][0:argc:2](argc); 
 
   return 0;
 }
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c
index 14421d9..814786b 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/misc.c
@@ -6,7 +6,7 @@ int main (void)
   int array[10], array2[10][10];
   int x, ii, jj ;
 
-  switch (array[:]) {  /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+  switch (array[:]) {  /* { dg-error "cannot be used as a condition for switch statement" } */
   case 1:
     x = 5;
     break;
@@ -17,7 +17,7 @@ int main (void)
     x = 9;
   }
 
-  switch (array2[:][:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+  switch (array2[:][:]) { /* { dg-error "cannot be used as a condition for switch statement" } */
   case 1:
     x = 5;
     break;
@@ -28,7 +28,7 @@ int main (void)
     x = 9;
   }
 
-  switch (array[:] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+  switch (array[:] + x) { /* { dg-error "cannot be used as a condition for switch statement" } */
   case 1:
     x = 5;
     break;
@@ -39,7 +39,7 @@ int main (void)
     x = 9;
   }
   
-  switch (array2[:][1:x:4] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
+  switch (array2[:][1:x:4] + x) { /* { dg-error "cannot be used as a condition for switch statement" } */
   case 1:
     x = 5;
     break;
@@ -50,36 +50,36 @@ int main (void)
     x = 9;
   }
 
-  for (ii = 0; ii < array[:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
+  for (ii = 0; ii < array[:]; ii++) /* { dg-error "cannot be used in a condition for a for-loop" } */
     {
       x = 2;
     }
 
-  for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
+  for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "cannot be used in a condition for a for-loop" } */
     {
       x = 3;
     }
 
-  for (; array2[:][:] < 2;) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
+  for (; array2[:][:] < 2;) /* { dg-error "cannot be used in a condition for a for-loop" } */
     x = 4;
 
 
-  while (array2[:][:]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
+  while (array2[:][:]) /* { dg-error "cannot be used as a condition for while statement" } */
     x = 3;
 
-  while (array[1:1:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
+  while (array[1:1:1]) /* { dg-error "cannot be used as a condition for while statement" } */
     x = 1;
 
-  while (ii != array2[1:x:3][1:2:1]) /* { dg-error "array notations cannot be used as a condition for while statement"  } */
+  while (ii != array2[1:x:3][1:2:1]) /* { dg-error "cannot be used as a condition for while statement"  } */
     x = 2;
 
-  do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c } } */
+  do { /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c } } */
     x = 3;
-  } while (ii != array2[:][:]); /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c++ } } */
+  } while (ii != array2[:][:]); /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c++ } } */
 
-  do {  /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c } } */
+  do {  /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c } } */
     x = 2;
-  } while (ii != (x + array2[:][1:x:2]) + 2); /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c++ } } */
+  } while (ii != (x + array2[:][1:x:2]) + 2); /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c++ } } */
   
   do { 
     x += 3;
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c
index b5e37ce..eb3c1f1 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c
@@ -10,6 +10,7 @@ int main (void)
   int array[10][10], array2[10];
 
   array[:][:] = array[:]; /* { dg-error "rank mismatch between" } */
+  /* { dg-error "invalid conversion" "" { target c++ } 12 } */
 
   x = array2[:]; /* { dg-error "cannot be scalar when" } */
 
