diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9541252..5d626ae 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -538,6 +538,8 @@ poplevel (int keep, int reverse, int functionbody)
   tree decl;
   int leaving_for_scope;
   scope_kind kind;
+  unsigned ix;
+  cp_label_binding *label_bind;
 
   timevar_push (TV_NAME_LOOKUP);
  restart:
@@ -682,10 +684,9 @@ poplevel (int keep, int reverse, int functionbody)
 	      /* Add it to the list of dead variables in the next
 		 outermost binding to that we can remove these when we
 		 leave that binding.  */
-	      current_binding_level->level_chain->dead_vars_from_for
-		= tree_cons (NULL_TREE, link,
-			     current_binding_level->level_chain->
-			     dead_vars_from_for);
+	      VEC_safe_push (tree, gc,
+			     current_binding_level->level_chain->dead_vars_from_for,
+			     link);
 
 	      /* Although we don't pop the cxx_binding, we do clear
 		 its SCOPE since the scope is going away now.  */
@@ -714,9 +715,10 @@ poplevel (int keep, int reverse, int functionbody)
 
   /* Remove declarations for any `for' variables from inner scopes
      that we kept around.  */
-  for (link = current_binding_level->dead_vars_from_for;
-       link; link = TREE_CHAIN (link))
-    pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link));
+  for (ix = VEC_length (tree, current_binding_level->dead_vars_from_for) - 1;
+       VEC_iterate (tree, current_binding_level->dead_vars_from_for, ix, decl);
+       ix--)
+    pop_binding (DECL_NAME (decl), decl);
 
   /* Restore the IDENTIFIER_TYPE_VALUEs.  */
   for (link = current_binding_level->type_shadowed;
@@ -724,10 +726,12 @@ poplevel (int keep, int reverse, int functionbody)
     SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));
 
   /* Restore the IDENTIFIER_LABEL_VALUEs for local labels.  */
-  for (link = current_binding_level->shadowed_labels;
-       link;
-       link = TREE_CHAIN (link))
-    pop_local_label (TREE_VALUE (link), TREE_PURPOSE (link));
+  for (ix = VEC_length (cp_label_binding,
+			current_binding_level->shadowed_labels) - 1;
+       VEC_iterate (cp_label_binding, current_binding_level->shadowed_labels,
+		    ix, label_bind);
+       ix--)
+    pop_local_label (label_bind->label, label_bind->prev_value);
 
   /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs
      list if a `using' declaration put them there.  The debugging
@@ -2499,16 +2503,17 @@ lookup_label (tree id)
 tree
 declare_local_label (tree id)
 {
-  tree decl, shadow;
+  tree decl, label_id;
+  cp_label_binding *bind;
 
-  /* Add a new entry to the SHADOWED_LABELS list so that when we leave
-     this scope we can restore the old value of IDENTIFIER_TYPE_VALUE.  */
-  shadow = tree_cons (IDENTIFIER_LABEL_VALUE (id), NULL_TREE,
-		      current_binding_level->shadowed_labels);
-  current_binding_level->shadowed_labels = shadow;
+  bind = VEC_safe_push (cp_label_binding, gc,
+			current_binding_level->shadowed_labels, NULL);
 
+  /* make_label_decl munges IDENTIFIER_LABEL_VALUE.  Save it.  */
+  label_id = IDENTIFIER_LABEL_VALUE (id);
   decl = make_label_decl (id, /*local_p=*/1);
-  TREE_VALUE (shadow) = decl;
+  bind->label = decl;
+  bind->prev_value = label_id;
 
   return decl;
 }
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index e5190eb..6375637 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -148,6 +148,16 @@ typedef struct GTY(()) cp_class_binding {
 DEF_VEC_O(cp_class_binding);
 DEF_VEC_ALLOC_O(cp_class_binding,gc);
 
+typedef struct GTY(()) cp_label_binding {
+  /* The bound LABEL_DECL.  */
+  tree label;
+  /* The previous IDENTIFIER_LABEL_VALUE.  */
+  tree prev_value;
+} cp_label_binding;
+
+DEF_VEC_O(cp_label_binding);
+DEF_VEC_ALLOC_O(cp_label_binding,gc);
+
 /* For each binding contour we allocate a binding_level structure
    which records the names defined in that contour.
    Contours include:
@@ -206,10 +216,9 @@ struct GTY(()) cp_binding_level {
        the class.  */
     tree type_shadowed;
 
-    /* A TREE_LIST.  Each TREE_VALUE is the LABEL_DECL for a local
-       label in this scope.  The TREE_PURPOSE is the previous value of
-       the IDENTIFIER_LABEL VALUE.  */
-    tree shadowed_labels;
+    /* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and
+       used for all binding levels.  */
+    VEC(cp_label_binding,gc) *shadowed_labels;
 
     /* For each level (except not the global one),
        a chain of BLOCK nodes for all the levels
@@ -225,9 +234,8 @@ struct GTY(()) cp_binding_level {
 
     /* List of VAR_DECLS saved from a previous for statement.
        These would be dead in ISO-conforming code, but might
-       be referenced in ARM-era code.  These are stored in a
-       TREE_LIST; the TREE_VALUE is the actual declaration.  */
-    tree dead_vars_from_for;
+       be referenced in ARM-era code.  */
+    VEC(tree,gc) *dead_vars_from_for;
 
     /* STATEMENT_LIST for statements in this binding contour.
        Only used at present for SK_CLEANUP temporary bindings.  */
