--- gcc/cp/cp-tree.h.jj	2019-12-05 10:03:04.111181297 +0100
+++ gcc/cp/cp-tree.h	2019-12-06 11:00:43.230257916 +0100
@@ -6321,7 +6321,9 @@ extern tree convert_for_arg_passing		(tr
 extern bool is_properly_derived_from		(tree, tree);
 extern tree initialize_reference		(tree, tree, int,
 						 tsubst_flags_t);
-extern tree extend_ref_init_temps		(tree, tree, vec<tree, va_gc>**);
+extern tree extend_ref_init_temps		(tree, tree,
+						 vec<tree, va_gc>**,
+						 tree * = NULL);
 extern tree make_temporary_var_for_ref_to_temp	(tree, tree);
 extern bool type_has_extended_temps		(tree);
 extern tree strip_top_quals			(tree);
--- gcc/cp/call.c.jj	2019-12-06 00:40:29.439856520 +0100
+++ gcc/cp/call.c	2019-12-06 11:00:17.111660971 +0100
@@ -11965,7 +11965,7 @@ make_temporary_var_for_ref_to_temp (tree
 
 static tree
 set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
-			  tree *initp)
+			  tree *initp, tree *cond_guard)
 {
   tree init;
   tree type;
@@ -11996,7 +11996,8 @@ set_up_extended_ref_temp (tree decl, tre
 
   /* Recursively extend temps in this initializer.  */
   TARGET_EXPR_INITIAL (expr)
-    = extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups);
+    = extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups,
+			     cond_guard);
 
   /* Any reference temp has a non-trivial initializer.  */
   DECL_NONTRIVIALLY_INITIALIZED_P (var) = true;
@@ -12037,7 +12038,24 @@ set_up_extended_ref_temp (tree decl, tre
 	{
 	  tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error);
 	  if (cleanup)
-	    vec_safe_push (*cleanups, cleanup);
+	    {
+	      if (cond_guard && cleanup != error_mark_node)
+		{
+		  if (*cond_guard == NULL_TREE)
+		    {
+		      *cond_guard = build_local_temp (boolean_type_node);
+		      add_decl_expr (*cond_guard);
+		      tree set = cp_build_modify_expr (UNKNOWN_LOCATION,
+						       *cond_guard, NOP_EXPR,
+						       boolean_false_node,
+						       tf_warning_or_error);
+		      finish_expr_stmt (set);
+		    }
+		  cleanup = build3 (COND_EXPR, void_type_node,
+				    *cond_guard, cleanup, NULL_TREE);
+		}
+	      vec_safe_push (*cleanups, cleanup);
+	    }
 	}
 
       /* We must be careful to destroy the temporary only
@@ -12142,7 +12160,8 @@ initialize_reference (tree type, tree ex
    which is bound either to a reference or a std::initializer_list.  */
 
 static tree
-extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups)
+extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups,
+			 tree *cond_guard)
 {
   tree sub = init;
   tree *p;
@@ -12150,20 +12169,52 @@ extend_ref_init_temps_1 (tree decl, tree
   if (TREE_CODE (sub) == COMPOUND_EXPR)
     {
       TREE_OPERAND (sub, 1)
-        = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 1), cleanups);
+	= extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 1), cleanups,
+				   cond_guard);
+      return init;
+    }
+  if (TREE_CODE (sub) == COND_EXPR)
+    {
+      tree cur_cond_guard = NULL_TREE;
+      if (TREE_OPERAND (sub, 1))
+	TREE_OPERAND (sub, 1)
+	  = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 1), cleanups,
+				     &cur_cond_guard);
+      if (cur_cond_guard)
+	{
+	  tree set = cp_build_modify_expr (UNKNOWN_LOCATION, cur_cond_guard,
+					   NOP_EXPR, boolean_true_node,
+					   tf_warning_or_error);
+	  TREE_OPERAND (sub, 1)
+	    = cp_build_compound_expr (set, TREE_OPERAND (sub, 1),
+				      tf_warning_or_error);
+	}
+      cur_cond_guard = NULL_TREE;
+      if (TREE_OPERAND (sub, 2))
+	TREE_OPERAND (sub, 2)
+	  = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 2), cleanups,
+				     &cur_cond_guard);
+      if (cur_cond_guard)
+	{
+	  tree set = cp_build_modify_expr (UNKNOWN_LOCATION, cur_cond_guard,
+					   NOP_EXPR, boolean_true_node,
+					   tf_warning_or_error);
+	  TREE_OPERAND (sub, 2)
+	    = cp_build_compound_expr (set, TREE_OPERAND (sub, 2),
+				      tf_warning_or_error);
+	}
       return init;
     }
   if (TREE_CODE (sub) != ADDR_EXPR)
     return init;
   /* Deal with binding to a subobject.  */
   for (p = &TREE_OPERAND (sub, 0);
-       (TREE_CODE (*p) == COMPONENT_REF
-	|| TREE_CODE (*p) == ARRAY_REF); )
+       TREE_CODE (*p) == COMPONENT_REF || TREE_CODE (*p) == ARRAY_REF; )
     p = &TREE_OPERAND (*p, 0);
   if (TREE_CODE (*p) == TARGET_EXPR)
     {
       tree subinit = NULL_TREE;
-      *p = set_up_extended_ref_temp (decl, *p, cleanups, &subinit);
+      *p = set_up_extended_ref_temp (decl, *p, cleanups, &subinit, cond_guard);
       recompute_tree_invariant_for_addr_expr (sub);
       if (init != sub)
 	init = fold_convert (TREE_TYPE (init), sub);
@@ -12178,13 +12229,14 @@ extend_ref_init_temps_1 (tree decl, tree
    lifetime to match that of DECL.  */
 
 tree
-extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups)
+extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups,
+		       tree *cond_guard)
 {
   tree type = TREE_TYPE (init);
   if (processing_template_decl)
     return init;
   if (TYPE_REF_P (type))
-    init = extend_ref_init_temps_1 (decl, init, cleanups);
+    init = extend_ref_init_temps_1 (decl, init, cleanups, cond_guard);
   else
     {
       tree ctor = init;
@@ -12203,7 +12255,8 @@ extend_ref_init_temps (tree decl, tree i
 	      /* The temporary array underlying a std::initializer_list
 		 is handled like a reference temporary.  */
 	      tree array = CONSTRUCTOR_ELT (ctor, 0)->value;
-	      array = extend_ref_init_temps_1 (decl, array, cleanups);
+	      array = extend_ref_init_temps_1 (decl, array, cleanups,
+					       cond_guard);
 	      CONSTRUCTOR_ELT (ctor, 0)->value = array;
 	    }
 	  else
@@ -12212,7 +12265,8 @@ extend_ref_init_temps (tree decl, tree i
 	      constructor_elt *p;
 	      vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
 	      FOR_EACH_VEC_SAFE_ELT (elts, i, p)
-		p->value = extend_ref_init_temps (decl, p->value, cleanups);
+		p->value = extend_ref_init_temps (decl, p->value, cleanups,
+						  cond_guard);
 	    }
 	  recompute_constructor_flags (ctor);
 	  if (decl_maybe_constant_var_p (decl) && TREE_CONSTANT (ctor))
--- gcc/testsuite/g++.dg/cpp0x/temp-extend2.C.jj	2019-12-06 11:08:09.694368207 +0100
+++ gcc/testsuite/g++.dg/cpp0x/temp-extend2.C	2019-12-06 11:10:58.040768156 +0100
@@ -0,0 +1,36 @@
+// PR c++/92831
+// { dg-do run { target c++11 } }
+
+template<typename T> using id = T;
+struct S { S () { s++; } ~S () { s--; } S (int) { s++; } static int s; };
+int S::s = 0;
+
+void
+bar (bool cond, bool cond2)
+{
+  if (S::s != (cond ? cond2 ? 7 : 5 : cond2 ? 8 : 9))
+    __builtin_abort ();
+}
+
+void
+foo (bool cond, bool cond2)
+{
+  int i = 1;
+  // temporary array has same lifetime as a
+  S&& a = id<S[3]>{1, 2, 3}[i];
+  // temporary S has same lifetime as b
+  const S& b = static_cast<const S&>(0);
+  // exactly one of the four temporaries is lifetime-extended
+  S&& c = cond ? cond2 ? id<S[3]>{1, 2, 3}[i] : static_cast<S&&>(0)
+	       : cond2 ? id<S[4]>{1, 2, 3, 4}[i] : id<S[5]>{1, 2, 3, 4, 5}[i];
+  bar (cond, cond2);
+}
+
+int
+main ()
+{
+  foo (true, true);
+  foo (true, false);
+  foo (false, true);
+  foo (false, false);
+}
