diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 3472f180543e..01ec9a739458 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1348,12 +1348,12 @@ public:
 
   bool maybe_zero_length_array_section (tree);
 
-  tree expand_array_base (tree, vec<omp_addr_token *> &, tree, unsigned *,
-			  c_omp_region_type, bool);
-  tree expand_component_selector (tree, vec<omp_addr_token *> &, tree,
-				  unsigned *, c_omp_region_type);
-  tree expand_map_clause (tree, tree, vec<omp_addr_token *> &,
-			  c_omp_region_type);
+  tree * expand_array_base (tree *, vec<omp_addr_token *> &, tree, unsigned *,
+			    c_omp_region_type, bool);
+  tree * expand_component_selector (tree *, vec<omp_addr_token *> &, tree,
+				    unsigned *, c_omp_region_type);
+  tree * expand_map_clause (tree *, tree, vec<omp_addr_token *> &,
+			    c_omp_region_type);
 };
 
 enum c_omp_directive_kind {
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 32699adc664c..0de3d350d023 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -3332,11 +3332,12 @@ c_omp_address_inspector::maybe_zero_length_array_section (tree clause)
    expression types here, because e.g. you can't have an array of
    references.  See also gimplify.cc:omp_expand_access_chain.  */
 
-static tree
-omp_expand_access_chain (tree c, tree expr, vec<omp_addr_token *> &addr_tokens,
-			 unsigned *idx)
+static tree *
+omp_expand_access_chain (tree *pc, tree expr,
+			 vec<omp_addr_token *> &addr_tokens, unsigned *idx)
 {
   using namespace omp_addr_tokenizer;
+  tree c = *pc;
   location_t loc = OMP_CLAUSE_LOCATION (c);
   unsigned i = *idx;
   tree c2 = NULL_TREE;
@@ -3364,35 +3365,36 @@ omp_expand_access_chain (tree c, tree expr, vec<omp_addr_token *> &addr_tokens,
       break;
 
     default:
-      return error_mark_node;
+      return NULL;
     }
 
   if (c2)
     {
       OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
       OMP_CLAUSE_CHAIN (c) = c2;
-      c = c2;
+      pc = &OMP_CLAUSE_CHAIN (c);
     }
 
   *idx = ++i;
 
   if (i < addr_tokens.length ()
       && addr_tokens[i]->type == ACCESS_METHOD)
-    return omp_expand_access_chain (c, expr, addr_tokens, idx);
+    return omp_expand_access_chain (pc, expr, addr_tokens, idx);
 
-  return c;
+  return pc;
 }
 
 /* Translate "array_base_decl access_method" to OMP mapping clauses.  */
 
-tree
-c_omp_address_inspector::expand_array_base (tree c,
+tree *
+c_omp_address_inspector::expand_array_base (tree *pc,
 					    vec<omp_addr_token *> &addr_tokens,
 					    tree expr, unsigned *idx,
 					    c_omp_region_type ort,
 					    bool decl_p)
 {
   using namespace omp_addr_tokenizer;
+  tree c = *pc;
   location_t loc = OMP_CLAUSE_LOCATION (c);
   int i = *idx;
   tree decl = addr_tokens[i + 1]->expr;
@@ -3417,7 +3419,7 @@ c_omp_address_inspector::expand_array_base (tree c,
 	  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
     {
       *idx = ++i;
-      return c;
+      return pc;
     }
 
   switch (addr_tokens[i + 1]->u.access_kind)
@@ -3663,7 +3665,7 @@ c_omp_address_inspector::expand_array_base (tree c,
 
     default:
       *idx = i + consume_tokens;
-      return error_mark_node;
+      return NULL;
     }
 
   if (c3)
@@ -3676,7 +3678,7 @@ c_omp_address_inspector::expand_array_base (tree c,
 	  OMP_CLAUSE_MAP_IMPLICIT (c2) = 1;
 	  OMP_CLAUSE_MAP_IMPLICIT (c3) = 1;
 	}
-      c = c3;
+      pc = &OMP_CLAUSE_CHAIN (c2);
     }
   else if (c2)
     {
@@ -3684,32 +3686,33 @@ c_omp_address_inspector::expand_array_base (tree c,
       OMP_CLAUSE_CHAIN (c) = c2;
       if (implicit_p)
 	OMP_CLAUSE_MAP_IMPLICIT (c2) = 1;
-      c = c2;
+      pc = &OMP_CLAUSE_CHAIN (c);
     }
 
   i += consume_tokens;
   *idx = i;
 
   if (target && chain_p && map_p)
-    return omp_expand_access_chain (c, expr, addr_tokens, idx);
+    return omp_expand_access_chain (pc, expr, addr_tokens, idx);
   else if (chain_p)
     while (*idx < addr_tokens.length ()
 	   && addr_tokens[*idx]->type == ACCESS_METHOD)
       (*idx)++;
 
-  return c;
+  return pc;
 }
 
 /* Translate "component_selector access_method" to OMP mapping clauses.  */
 
-tree
-c_omp_address_inspector::expand_component_selector (tree c,
+tree *
+c_omp_address_inspector::expand_component_selector (tree *pc,
 						    vec<omp_addr_token *>
 						      &addr_tokens,
 						    tree expr, unsigned *idx,
 						    c_omp_region_type ort)
 {
   using namespace omp_addr_tokenizer;
+  tree c = *pc;
   location_t loc = OMP_CLAUSE_LOCATION (c);
   unsigned i = *idx;
   tree c2 = NULL_TREE, c3 = NULL_TREE;
@@ -3817,7 +3820,7 @@ c_omp_address_inspector::expand_component_selector (tree c,
 
     default:
       *idx = i + 2;
-      return error_mark_node;
+      return NULL;
     }
 
   if (c3)
@@ -3825,33 +3828,33 @@ c_omp_address_inspector::expand_component_selector (tree c,
       OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c);
       OMP_CLAUSE_CHAIN (c2) = c3;
       OMP_CLAUSE_CHAIN (c) = c2;
-      c = c3;
+      pc = &OMP_CLAUSE_CHAIN (c2);
     }
   else if (c2)
     {
       OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
       OMP_CLAUSE_CHAIN (c) = c2;
-      c = c2;
+      pc = &OMP_CLAUSE_CHAIN (c);
     }
 
   i += 2;
   *idx = i;
 
   if (target && chain_p && map_p)
-    return omp_expand_access_chain (c, expr, addr_tokens, idx);
+    return omp_expand_access_chain (pc, expr, addr_tokens, idx);
   else if (chain_p)
     while (*idx < addr_tokens.length ()
 	   && addr_tokens[*idx]->type == ACCESS_METHOD)
       (*idx)++;
 
-  return c;
+  return pc;
 }
 
 /* Expand a map clause into a group of mapping clauses, creating nodes to
    attach/detach pointers and so forth as necessary.  */
 
-tree
-c_omp_address_inspector::expand_map_clause (tree c, tree expr,
+tree *
+c_omp_address_inspector::expand_map_clause (tree *pc, tree expr,
 					    vec<omp_addr_token *> &addr_tokens,
 					    c_omp_region_type ort)
 {
@@ -3867,18 +3870,18 @@ c_omp_address_inspector::expand_map_clause (tree c, tree expr,
 	  && addr_tokens[i]->u.structure_base_kind == BASE_DECL
 	  && addr_tokens[i + 1]->type == ACCESS_METHOD)
 	{
-	  c = expand_array_base (c, addr_tokens, expr, &i, ort, true);
-	  if (c == error_mark_node)
-	    return error_mark_node;
+	  pc = expand_array_base (pc, addr_tokens, expr, &i, ort, true);
+	  if (pc == NULL)
+	    return NULL;
 	}
       else if (remaining >= 2
 	       && addr_tokens[i]->type == ARRAY_BASE
 	       && addr_tokens[i]->u.structure_base_kind == BASE_ARBITRARY_EXPR
 	       && addr_tokens[i + 1]->type == ACCESS_METHOD)
 	{
-	  c = expand_array_base (c, addr_tokens, expr, &i, ort, false);
-	  if (c == error_mark_node)
-	    return error_mark_node;
+	  pc = expand_array_base (pc, addr_tokens, expr, &i, ort, false);
+	  if (pc == NULL)
+	    return NULL;
 	}
       else if (remaining >= 2
 	       && addr_tokens[i]->type == STRUCTURE_BASE
@@ -3905,18 +3908,18 @@ c_omp_address_inspector::expand_map_clause (tree c, tree expr,
 		i++;
 	      break;
 	    default:
-	      return error_mark_node;
+	      return NULL;
 	    }
 	}
       else if (remaining >= 2
 	       && addr_tokens[i]->type == COMPONENT_SELECTOR
 	       && addr_tokens[i + 1]->type == ACCESS_METHOD)
 	{
-	  c = expand_component_selector (c, addr_tokens, expr, &i, ort);
+	  pc = expand_component_selector (pc, addr_tokens, expr, &i, ort);
 	  /* We used 'expr', so these must have been the last tokens.  */
 	  gcc_assert (i == length);
-	  if (c == error_mark_node)
-	    return error_mark_node;
+	  if (pc == NULL)
+	    return NULL;
 	}
       else if (remaining >= 3
 	       && addr_tokens[i]->type == COMPONENT_SELECTOR
@@ -3934,9 +3937,9 @@ c_omp_address_inspector::expand_map_clause (tree c, tree expr,
     }
 
   if (i == length)
-    return c;
+    return pc;
 
-  return error_mark_node;
+  return NULL;
 }
 
 /* Given a mapper function MAPPER_FN, recursively scan through the map clauses
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 5c1b21392838..12be66bd49be 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -14043,8 +14043,9 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
 /* Handle array sections for clause C.  */
 
 static bool
-handle_omp_array_sections (tree c, enum c_omp_region_type ort)
+handle_omp_array_sections (tree *pc, enum c_omp_region_type ort)
 {
+  tree c = *pc;
   bool maybe_zero_len = false;
   unsigned int first_non_one = 0;
   auto_vec<tree, 10> types;
@@ -14266,8 +14267,8 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort)
 
       c_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
 
-      tree nc = ai.expand_map_clause (c, first, addr_tokens, ort);
-      if (nc != error_mark_node)
+      tree *npc = ai.expand_map_clause (pc, first, addr_tokens, ort);
+      if (npc != NULL)
 	{
 	  if (ai.maybe_zero_length_array_section (c))
 	    OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
@@ -14616,12 +14617,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	  t = OMP_CLAUSE_DECL (c);
 	  if (TREE_CODE (t) == OMP_ARRAY_SECTION)
 	    {
-	      if (handle_omp_array_sections (c, ort))
+	      if (handle_omp_array_sections (pc, ort))
 		{
 		  remove = true;
 		  break;
 		}
 
+	      c = *pc;
 	      t = OMP_CLAUSE_DECL (c);
 	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
 		  && OMP_CLAUSE_REDUCTION_INSCAN (c))
@@ -15237,10 +15239,12 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	    last_iterators = NULL_TREE;
 	  if (TREE_CODE (t) == OMP_ARRAY_SECTION)
 	    {
-	      if (handle_omp_array_sections (c, ort))
+	      if (handle_omp_array_sections (pc, ort))
 		remove = true;
-	      else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-		       && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ)
+	      else if ((c = *pc)
+		       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
+		       && (OMP_CLAUSE_DEPEND_KIND (c)
+			   == OMP_CLAUSE_DEPEND_DEPOBJ))
 		{
 		  error_at (OMP_CLAUSE_LOCATION (c),
 			    "%<depend%> clause with %<depobj%> dependence "
@@ -15356,10 +15360,11 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 		grp_start_p = pc;
 		grp_sentinel = OMP_CLAUSE_CHAIN (c);
 
-		if (handle_omp_array_sections (c, ort))
+		if (handle_omp_array_sections (pc, ort))
 		  remove = true;
 		else
 		  {
+		    c = *pc;
 		    t = OMP_CLAUSE_DECL (c);
 		    if (!omp_mappable_type (TREE_TYPE (t)))
 		      {
@@ -15647,10 +15652,10 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	      {
 		grp_start_p = pc;
 		grp_sentinel = OMP_CLAUSE_CHAIN (c);
-		tree nc = ai.expand_map_clause (c, OMP_CLAUSE_DECL (c),
-						addr_tokens, ort);
-		if (nc != error_mark_node)
-		  c = nc;
+		tree *npc = ai.expand_map_clause (pc, OMP_CLAUSE_DECL (c),
+						  addr_tokens, ort);
+		if (npc != NULL)
+		  c = *npc;
 	      }
 	  }
 	  break;
@@ -15750,10 +15755,11 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	  t = OMP_CLAUSE_DECL (c);
 	  if (TREE_CODE (t) == OMP_ARRAY_SECTION)
 	    {
-	      if (handle_omp_array_sections (c, ort))
+	      if (handle_omp_array_sections (pc, ort))
 		remove = true;
 	      else
 		{
+		  c = *pc;
 		  t = OMP_CLAUSE_DECL (c);
 		  while (TREE_CODE (t) == ARRAY_REF)
 		    t = TREE_OPERAND (t, 0);
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 5fff643411a0..1ef00cf9ab3c 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -5524,8 +5524,9 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
 /* Handle array sections for clause C.  */
 
 static bool
-handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
+handle_omp_array_sections (tree *pc, tree **pnext, enum c_omp_region_type ort)
 {
+  tree c = *pc;
   bool maybe_zero_len = false;
   unsigned int first_non_one = 0;
   auto_vec<tree, 10> types;
@@ -5778,23 +5779,27 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
 
 	  cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
 
-	  tree nc = ai.expand_map_clause (c, first, addr_tokens, ort);
-	  if (nc != error_mark_node)
+	  tree* npc = ai.expand_map_clause (pc, first, addr_tokens, ort);
+	  if (npc != NULL)
 	    {
 	      using namespace omp_addr_tokenizer;
 
+	      c = *pc;
+
 	      if (ai.maybe_zero_length_array_section (c))
 		OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
 
 	      /* !!! If we're accessing a base decl via chained access
 		 methods (e.g. multiple indirections), duplicate clause
 		 detection won't work properly.  Skip it in that case.  */
-	      if ((addr_tokens[0]->type == STRUCTURE_BASE
+	      if (pnext
+		  && (addr_tokens[0]->type == STRUCTURE_BASE
 		   || addr_tokens[0]->type == ARRAY_BASE)
 		  && addr_tokens[0]->u.structure_base_kind == BASE_DECL
 		  && addr_tokens[1]->type == ACCESS_METHOD
 		  && omp_access_chain_p (addr_tokens, 1))
-		c = nc;
+		/* NPC points to the last node in the new sequence.  */
+		*pnext = npc;
 
 	      return false;
 	    }
@@ -6920,7 +6925,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	  t = OMP_CLAUSE_DECL (c);
 	  if (TREE_CODE (t) == OMP_ARRAY_SECTION)
 	    {
-	      if (handle_omp_array_sections (c, ort))
+	      if (handle_omp_array_sections (pc, NULL, ort))
 		{
 		  remove = true;
 		  break;
@@ -7960,7 +7965,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 
 	  if (TREE_CODE (t) == OMP_ARRAY_SECTION)
 	    {
-	      if (handle_omp_array_sections (c, ort))
+	      if (handle_omp_array_sections (pc, NULL, ort))
 		remove = true;
 	      else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
 		       && (OMP_CLAUSE_DEPEND_KIND (c)
@@ -8129,10 +8134,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 		grp_start_p = pc;
 		grp_sentinel = OMP_CLAUSE_CHAIN (c);
 
-		if (handle_omp_array_sections (c, ort))
+		tree *pnext = NULL;
+		if (handle_omp_array_sections (pc, &pnext, ort))
 		  remove = true;
 		else
 		  {
+		    /* We might have replaced the clause, so refresh C.  */
+		    c = *pc;
 		    t = OMP_CLAUSE_DECL (c);
 		    if (TREE_CODE (t) != OMP_ARRAY_SECTION
 			&& !type_dependent_expression_p (t)
@@ -8230,6 +8238,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 		     clauses, reset the OMP_CLAUSE_SIZE (representing a bias)
 		     to zero here.  */
 		  OMP_CLAUSE_SIZE (c) = size_zero_node;
+		if (pnext)
+		  c = *pnext;
 		break;
 	      }
 	    else if (type_dependent_expression_p (t))
@@ -8472,10 +8482,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	      {
 		grp_start_p = pc;
 		grp_sentinel = OMP_CLAUSE_CHAIN (c);
-		tree nc = ai.expand_map_clause (c, OMP_CLAUSE_DECL (c),
-						addr_tokens, ort);
-		if (nc != error_mark_node)
-		  c = nc;
+		tree *npc = ai.expand_map_clause (pc, OMP_CLAUSE_DECL (c),
+						  addr_tokens, ort);
+		if (npc != NULL)
+		  c = *npc;
 	      }
 	  }
 	  break;
@@ -8713,10 +8723,11 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	  t = OMP_CLAUSE_DECL (c);
 	  if (TREE_CODE (t) == OMP_ARRAY_SECTION)
 	    {
-	      if (handle_omp_array_sections (c, ort))
+	      if (handle_omp_array_sections (pc, NULL, ort))
 		remove = true;
 	      else
 		{
+		  c = *pc;
 		  t = OMP_CLAUSE_DECL (c);
 		  while (TREE_CODE (t) == OMP_ARRAY_SECTION)
 		    t = TREE_OPERAND (t, 0);
