Merge from trunk revision 837eb12629dd8a8a45fac9b8db57b29ecda46f14.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3de0c1..95ca91e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+2022-02-16  Andrew MacLeod  <amacleod@redhat.com>
+
+	* gimple-range-gori.cc (gori_compute::condexpr_adjust): Use
+	range_compatible_p instead of direct type comparison.
+
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/104544
+	* combine.cc (try_combine): When looking for insn whose links
+	should be updated from i3 to i2, don't stop on debug insns, instead
+	skip over them.
+
+2022-02-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/100056
+	* config/aarch64/iterators.md (LOGICAL_OR_PLUS): New iterator.
+	* config/aarch64/aarch64.md: Extend the PR100056 patterns
+	to handle plus in the same way as ior, if the operands have
+	no set bits in common.
+
 2022-02-15  Andrew MacLeod  <amacleod@redhat.com>
 
 	PR tree-optimization/104526
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 07f9f51..2215f56 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220216
+20220217
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index cab2746..4575f2f 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,37 @@
+2022-02-16  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/104560
+	* diagnostic-manager.cc (diagnostic_manager::build_emission_path):
+	Add region creation events for globals of interest.
+	(null_assignment_sm_context::get_old_program_state): New.
+	(diagnostic_manager::add_events_for_eedge): Move check for
+	changing dynamic extents from PK_BEFORE_STMT case to after the
+	switch on the dst_point's kind so that we can emit them for the
+	final stmt in a basic block.
+	* engine.cc (impl_sm_context::get_old_program_state): New.
+	* sm-malloc.cc (malloc_state_machine::get_default_state): Rewrite
+	detection of m_non_heap to use get_memory_space.
+	(free_of_non_heap::free_of_non_heap): Add freed_reg param.
+	(free_of_non_heap::subclass_equal_p): Update for changes to
+	fields.
+	(free_of_non_heap::emit): Drop m_kind in favor of
+	get_memory_space.
+	(free_of_non_heap::describe_state_change): Remove logic for
+	detecting alloca.
+	(free_of_non_heap::mark_interesting_stuff): Add region-creation of
+	m_freed_reg.
+	(free_of_non_heap::get_memory_space): New.
+	(free_of_non_heap::kind): Drop enum.
+	(free_of_non_heap::m_freed_reg): New field.
+	(free_of_non_heap::m_kind): Drop field.
+	(malloc_state_machine::on_stmt): Drop transition to m_non_heap.
+	(malloc_state_machine::handle_free_of_non_heap): New function,
+	split out from on_deallocator_call and on_realloc_call, adding
+	detection of the freed region.
+	(malloc_state_machine::on_deallocator_call): Use it.
+	(malloc_state_machine::on_realloc_call): Likewise.
+	* sm.h (sm_context::get_old_program_state): New vfunc.
+
 2022-02-15  David Malcolm  <dmalcolm@redhat.com>
 
 	PR analyzer/104524
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 80bca6a..680016e 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -1272,6 +1272,35 @@
 
   interesting_t interest;
   pb.get_pending_diagnostic ()->mark_interesting_stuff (&interest);
+
+  /* Add region creation events for any globals of interest, at the
+     beginning of the path.  */
+  {
+    for (auto reg : interest.m_region_creation)
+      switch (reg->get_memory_space ())
+	{
+	default:
+	  continue;
+	case MEMSPACE_CODE:
+	case MEMSPACE_GLOBALS:
+	case MEMSPACE_READONLY_DATA:
+	  {
+	    const region *base_reg = reg->get_base_region ();
+	    if (tree decl = base_reg->maybe_get_decl ())
+	      if (DECL_P (decl)
+		  && DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
+		{
+		  emission_path->add_region_creation_event
+		    (reg,
+		     DECL_SOURCE_LOCATION (decl),
+		     NULL_TREE,
+		     0);
+		}
+	  }
+	}
+  }
+
+  /* Walk EPATH, adding events as appropriate.  */
   for (unsigned i = 0; i < epath.m_edges.length (); i++)
     {
       const exploded_edge *eedge = epath.m_edges[i];
@@ -1569,6 +1598,11 @@
     return NULL_TREE;
   }
 
+  const program_state *get_old_program_state () const FINAL OVERRIDE
+  {
+    return m_old_state;
+  }
+
   const program_state *m_old_state;
   const program_state *m_new_state;
   const gimple *m_stmt;
@@ -1729,46 +1763,47 @@
 		  break;
 	      }
 
-	    /* Look for changes in dynamic extents, which will identify
-	       the creation of heap-based regions and alloca regions.  */
-	    if (interest)
-	      {
-		const region_model *src_model = src_state.m_region_model;
-		const region_model *dst_model = dst_state.m_region_model;
-		if (src_model->get_dynamic_extents ()
-		    != dst_model->get_dynamic_extents ())
-		{
-		  unsigned i;
-		  const region *reg;
-		  FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg)
-		    {
-		      const region *base_reg = reg->get_base_region ();
-		      const svalue *old_extents
-			= src_model->get_dynamic_extents (base_reg);
-		      const svalue *new_extents
-			= dst_model->get_dynamic_extents (base_reg);
-		      if (old_extents == NULL && new_extents != NULL)
-			switch (base_reg->get_kind ())
-			  {
-			  default:
-			    break;
-			  case RK_HEAP_ALLOCATED:
-			  case RK_ALLOCA:
-			    emission_path->add_region_creation_event
-			      (reg,
-			       src_point.get_location (),
-			       src_point.get_fndecl (),
-			       src_stack_depth);
-			    break;
-			  }
-		    }
-		}
-	      }
 	  }
       }
       break;
     }
 
+  /* Look for changes in dynamic extents, which will identify
+     the creation of heap-based regions and alloca regions.  */
+  if (interest)
+    {
+      const region_model *src_model = src_state.m_region_model;
+      const region_model *dst_model = dst_state.m_region_model;
+      if (src_model->get_dynamic_extents ()
+	  != dst_model->get_dynamic_extents ())
+	{
+	  unsigned i;
+	  const region *reg;
+	  FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg)
+	    {
+	      const region *base_reg = reg->get_base_region ();
+	      const svalue *old_extents
+		= src_model->get_dynamic_extents (base_reg);
+	      const svalue *new_extents
+		= dst_model->get_dynamic_extents (base_reg);
+	      if (old_extents == NULL && new_extents != NULL)
+		switch (base_reg->get_kind ())
+		  {
+		  default:
+		    break;
+		  case RK_HEAP_ALLOCATED:
+		  case RK_ALLOCA:
+		    emission_path->add_region_creation_event
+		      (reg,
+		       src_point.get_location (),
+		       src_point.get_fndecl (),
+		       src_stack_depth);
+		    break;
+		  }
+	    }
+	}
+    }
+
   if (pb.get_feasibility_problem ()
       && &pb.get_feasibility_problem ()->m_eedge == &eedge)
     {
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index bff3779..f5b85ce 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -500,6 +500,11 @@
     return m_unknown_side_effects;
   }
 
+  const program_state *get_old_program_state () const FINAL OVERRIDE
+  {
+    return m_old_state;
+  }
+
   log_user m_logger;
   exploded_graph &m_eg;
   exploded_node *m_enode_for_diag;
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 69e8fa7..d4d7816 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -72,6 +72,7 @@
 #include "tree-phinodes.h"
 #include "tree-ssa-operands.h"
 #include "ssa-iterators.h"
+#include "calls.h"
 
 #if ENABLE_ANALYZER
 
@@ -1271,13 +1272,14 @@
 	 in region-model-impl-calls.cc.
 	 Having them split out into separate functions makes it easier
 	 to put breakpoints on the handling of specific functions.  */
+      int callee_fndecl_flags = flags_from_decl_or_type (callee_fndecl);
 
       if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
 	  && gimple_builtin_call_types_compatible_p (call, callee_fndecl))
 	switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
 	  {
 	  default:
-	    if (!DECL_PURE_P (callee_fndecl))
+	    if (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
 	      unknown_side_effects = true;
 	    break;
 	  case BUILT_IN_ALLOCA:
@@ -1433,7 +1435,7 @@
 	  /* Handle in "on_call_post".  */
 	}
       else if (!fndecl_has_gimple_body_p (callee_fndecl)
-	       && !DECL_PURE_P (callee_fndecl)
+	       && (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
 	       && !fndecl_built_in_p (callee_fndecl))
 	unknown_side_effects = true;
     }
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 2f7a387..a5fa60d 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -356,10 +356,16 @@
     if (const region_svalue *ptr = sval->dyn_cast_region_svalue ())
       {
 	const region *reg = ptr->get_pointee ();
-	const region *base_reg = reg->get_base_region ();
-	if (base_reg->get_kind () == RK_DECL
-	    || base_reg->get_kind () == RK_STRING)
-	  return m_non_heap;
+	switch (reg->get_memory_space ())
+	  {
+	  default:
+	    break;
+	  case MEMSPACE_CODE:
+	  case MEMSPACE_GLOBALS:
+	  case MEMSPACE_STACK:
+	  case MEMSPACE_READONLY_DATA:
+	    return m_non_heap;
+	  }
       }
     return m_start;
   }
@@ -425,6 +431,11 @@
 			  const gcall *call,
 			  const deallocator_set *deallocators,
 			  bool returns_nonnull = false) const;
+  void handle_free_of_non_heap (sm_context *sm_ctxt,
+				const supernode *node,
+				const gcall *call,
+				tree arg,
+				const deallocator *d) const;
   void on_deallocator_call (sm_context *sm_ctxt,
 			    const supernode *node,
 			    const gcall *call,
@@ -1289,8 +1300,9 @@
 {
 public:
   free_of_non_heap (const malloc_state_machine &sm, tree arg,
+		    const region *freed_reg,
 		    const char *funcname)
-  : malloc_diagnostic (sm, arg), m_funcname (funcname), m_kind (KIND_UNKNOWN)
+  : malloc_diagnostic (sm, arg), m_freed_reg (freed_reg), m_funcname (funcname)
   {
   }
 
@@ -1300,7 +1312,8 @@
     FINAL OVERRIDE
   {
     const free_of_non_heap &other = (const free_of_non_heap &)base_other;
-    return (same_tree_p (m_arg, other.m_arg) && m_kind == other.m_kind);
+    return (same_tree_p (m_arg, other.m_arg)
+	    && m_freed_reg == other.m_freed_reg);
   }
 
   bool emit (rich_location *rich_loc) FINAL OVERRIDE
@@ -1308,44 +1321,32 @@
     auto_diagnostic_group d;
     diagnostic_metadata m;
     m.add_cwe (590); /* CWE-590: Free of Memory not on the Heap.  */
-    switch (m_kind)
+    switch (get_memory_space ())
       {
       default:
+      case MEMSPACE_HEAP:
 	gcc_unreachable ();
-      case KIND_UNKNOWN:
+      case MEMSPACE_UNKNOWN:
+      case MEMSPACE_CODE:
+      case MEMSPACE_GLOBALS:
+      case MEMSPACE_READONLY_DATA:
 	return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
 			     "%<%s%> of %qE which points to memory"
 			     " not on the heap",
 			     m_funcname, m_arg);
 	break;
-      case KIND_ALLOCA:
+      case MEMSPACE_STACK:
 	return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
-			     "%<%s%> of memory allocated on the stack by"
-			     " %qs (%qE) will corrupt the heap",
-			     m_funcname, "alloca", m_arg);
+			     "%<%s%> of %qE which points to memory"
+			     " on the stack",
+			     m_funcname, m_arg);
 	break;
       }
   }
 
-  label_text describe_state_change (const evdesc::state_change &change)
+  label_text describe_state_change (const evdesc::state_change &)
     FINAL OVERRIDE
   {
-    /* Attempt to reconstruct what kind of pointer it is.
-       (It seems neater for this to be a part of the state, though).  */
-    if (change.m_expr && TREE_CODE (change.m_expr) == SSA_NAME)
-      {
-	gimple *def_stmt = SSA_NAME_DEF_STMT (change.m_expr);
-	if (gcall *call = dyn_cast <gcall *> (def_stmt))
-	  {
-	    if (is_special_named_call_p (call, "alloca", 1)
-		|| is_special_named_call_p (call, "__builtin_alloca", 1))
-	      {
-		m_kind = KIND_ALLOCA;
-		return label_text::borrow
-		  ("memory is allocated on the stack here");
-	      }
-	  }
-      }
     return label_text::borrow ("pointer is from here");
   }
 
@@ -1354,14 +1355,23 @@
     return ev.formatted_print ("call to %qs here", m_funcname);
   }
 
-private:
-  enum kind
+  void mark_interesting_stuff (interesting_t *interest) FINAL OVERRIDE
   {
-    KIND_UNKNOWN,
-    KIND_ALLOCA
-  };
+    if (m_freed_reg)
+      interest->add_region_creation (m_freed_reg);
+  }
+
+private:
+  enum memory_space get_memory_space () const
+  {
+    if (m_freed_reg)
+      return m_freed_reg->get_memory_space ();
+    else
+      return MEMSPACE_UNKNOWN;
+  }
+
+  const region *m_freed_reg;
   const char *m_funcname;
-  enum kind m_kind;
 };
 
 /* struct allocation_state : public state_machine::state.  */
@@ -1701,26 +1711,6 @@
     if (any_pointer_p (lhs))
       on_zero_assignment (sm_ctxt, stmt,lhs);
 
-  /* If we have "LHS = &EXPR;" and EXPR is something other than a MEM_REF,
-     transition LHS from start to non_heap.
-     Doing it for ADDR_EXPR(MEM_REF()) is likely wrong, and can lead to
-     unbounded chains of unmergeable sm-state on pointer arithmetic in loops
-     when optimization is enabled.  */
-  if (const gassign *assign_stmt = dyn_cast <const gassign *> (stmt))
-    {
-      enum tree_code op = gimple_assign_rhs_code (assign_stmt);
-      if (op == ADDR_EXPR)
-	{
-	  tree lhs = gimple_assign_lhs (assign_stmt);
-	  if (lhs)
-	    {
-	      tree addr_expr = gimple_assign_rhs1 (assign_stmt);
-	      if (TREE_CODE (TREE_OPERAND (addr_expr, 0)) != MEM_REF)
-		sm_ctxt->on_transition (node, stmt, lhs, m_start, m_non_heap);
-	    }
-	}
-    }
-
   /* Handle dereferences.  */
   for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
     {
@@ -1789,6 +1779,30 @@
     }
 }
 
+/* Handle deallocations of non-heap pointers.
+   non-heap -> stop, with warning.  */
+
+void
+malloc_state_machine::handle_free_of_non_heap (sm_context *sm_ctxt,
+					       const supernode *node,
+					       const gcall *call,
+					       tree arg,
+					       const deallocator *d) const
+{
+  tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
+  const region *freed_reg = NULL;
+  if (const program_state *old_state = sm_ctxt->get_old_program_state ())
+    {
+      const region_model *old_model = old_state->m_region_model;
+      const svalue *ptr_sval = old_model->get_rvalue (arg, NULL);
+      freed_reg = old_model->deref_rvalue (ptr_sval, arg, NULL);
+    }
+  sm_ctxt->warn (node, call, arg,
+		 new free_of_non_heap (*this, diag_arg, freed_reg,
+				       d->m_name));
+  sm_ctxt->set_next_state (call, arg, m_stop);
+}
+
 void
 malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt,
 					   const supernode *node,
@@ -1835,11 +1849,7 @@
   else if (state == m_non_heap)
     {
       /* non-heap -> stop, with warning.  */
-      tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
-      sm_ctxt->warn (node, call, arg,
-		     new free_of_non_heap (*this, diag_arg,
-					   d->m_name));
-      sm_ctxt->set_next_state (call, arg, m_stop);
+      handle_free_of_non_heap (sm_ctxt, node, call, arg, d);
     }
 }
 
@@ -1894,11 +1904,7 @@
   else if (state == m_non_heap)
     {
       /* non-heap -> stop, with warning.  */
-      tree diag_arg = sm_ctxt->get_diagnostic_tree (arg);
-      sm_ctxt->warn (node, call, arg,
-		     new free_of_non_heap (*this, diag_arg,
-					   d->m_name));
-      sm_ctxt->set_next_state (call, arg, m_stop);
+      handle_free_of_non_heap (sm_ctxt, node, call, arg, d);
       if (path_context *path_ctxt = sm_ctxt->get_path_context ())
 	path_ctxt->terminate_path ();
     }
diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h
index fccfc88..7ce1c73 100644
--- a/gcc/analyzer/sm.h
+++ b/gcc/analyzer/sm.h
@@ -274,6 +274,10 @@
   /* Are we handling an external function with unknown side effects?  */
   virtual bool unknown_side_effects_p () const { return false; }
 
+  virtual const program_state *get_old_program_state () const = 0;
+
+  const svalue *get_old_svalue (tree expr) const;
+
 protected:
   sm_context (int sm_idx, const state_machine &sm)
   : m_sm_idx (sm_idx), m_sm (sm) {}
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 340e2c0..77950b4 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,16 @@
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/104531
+	* c-omp.cc (c_finish_omp_atomic): For MIN_EXPR/MAX_EXPR, try first
+	build_binary_op with LT_EXPR and only if that doesn't return
+	error_mark_node call build_modify_expr.
+
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/104510
+	* c-common.cc (shorten_compare): Convert original arguments to
+	the original *restype_ptr when mixing binary and decimal float.
+
 2022-02-14  Richard Biener  <rguenther@suse.de>
 
 	PR c/104505
diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index 15251ef..d2e480a 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -623,7 +623,11 @@
   if (TARGET_FRSQRTES)
     builtin_define ("__RSQRTEF__");
   if (TARGET_FLOAT128_TYPE)
-    builtin_define ("__FLOAT128_TYPE__");
+      builtin_define ("__FLOAT128_TYPE__");
+  if (ibm128_float_type_node)
+    builtin_define ("__SIZEOF_IBM128__=16");
+  if (ieee128_float_type_node)
+    builtin_define ("__SIZEOF_FLOAT128__=16");
 #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
   builtin_define ("__BUILTIN_CPU_SUPPORTS__");
 #endif
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 90d4a79..2bc4c0e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2022-02-16  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/104507
+	* constexpr.cc (potential_constant_expression_1)
+	<case NON_DEPENDENT_EXPR>: Return false instead of recursing.
+	Assert tf_error isn't set.
+
 2022-02-15  Jason Merrill  <jason@redhat.com>
 
 	PR c++/104107
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index b9d0735..8274a4d 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,23 @@
+2022-02-16  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	* d-builtins.cc (d_build_builtins_module): Set purity of DECL_PURE_P
+	functions to PURE::const_.
+	* d-gimplify.cc (bit_field_ref): New function.
+	(d_gimplify_modify_expr): Handle implicit casting for assignments to
+	bit-fields.
+	(d_gimplify_unary_expr): New function.
+	(d_gimplify_binary_expr): New function.
+	(d_gimplify_expr): Handle UNARY_CLASS_P and BINARY_CLASS_P.
+	* d-target.cc (Target::_init): Initialize bitFieldStyle.
+	(TargetCPP::parameterType): Update signature.
+	(Target::supportsLinkerDirective): New function.
+	* dmd/MERGE: Merge upstream dmd 52844d4b1.
+	* expr.cc (ExprVisitor::visit (ThrowExp *)): New function.
+	* types.cc (d_build_bitfield_integer_type): New function.
+	(insert_aggregate_bitfield): New function.
+	(layout_aggregate_members): Handle inserting bit-fields into an
+	aggregate type.
+
 2022-01-31  Martin Liska  <mliska@suse.cz>
 
 	PR d/104287
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5230f00..7ddcc12 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,62 @@
+2022-02-16  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/104560
+	* g++.dg/analyzer/placement-new.C: Update expected wording.
+	* g++.dg/analyzer/pr100244.C: Likewise.
+	* gcc.dg/analyzer/attr-malloc-1.c (test_7): Likewise.
+	* gcc.dg/analyzer/malloc-1.c (test_24): Likewise.
+	(test_25): Likewise.
+	(test_26): Likewise.
+	(test_50a, test_50b, test_50c): New.
+	* gcc.dg/analyzer/malloc-callbacks.c (test_5): Update expected
+	wording.
+	* gcc.dg/analyzer/malloc-paths-8.c: Likewise.
+	* gcc.dg/analyzer/pr104560-1.c: New test.
+	* gcc.dg/analyzer/pr104560-2.c: New test.
+	* gcc.dg/analyzer/realloc-1.c (test_7): Updated expected wording.
+	* gcc.dg/analyzer/vla-1.c (test_2): New.  Prune output from
+	-Wfree-nonheap-object.
+
+2022-02-16  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/104507
+	* g++.dg/template/non-dependent21.C: New test.
+
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/104448
+	* gcc.target/i386/pr104448.c: New test.
+
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/104544
+	* gcc.dg/pr104544.c: New test.
+
+2022-02-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	* gcc.target/aarch64/atomic-inst-cas.c: Add
+	-Wno-invalid-memory-model.
+
+2022-02-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	* gcc.target/aarch64/bic-bitmask-1.c: Remove XFAIL.
+
+2022-02-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/100056
+	* gcc.target/aarch64/pr100056.c: XFAIL the original UBFIZ test
+	and instead expect two UBFIZs + two ADD UXTBs.
+
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/104531
+	* c-c++-common/gomp/atomic-31.c: New test.
+
+2022-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/104510
+	* gcc.dg/dfp/pr104510.c: New test.
+
 2022-02-15  Peter Bergner  <bergner@linux.ibm.com>
 
 	* gcc.target/powerpc/htm-1.c: Retry intermittent failing tbegins.
diff --git a/gcc/testsuite/g++.dg/analyzer/placement-new.C b/gcc/testsuite/g++.dg/analyzer/placement-new.C
index b648a42..8905549 100644
--- a/gcc/testsuite/g++.dg/analyzer/placement-new.C
+++ b/gcc/testsuite/g++.dg/analyzer/placement-new.C
@@ -20,9 +20,9 @@
 
 void test_3 (void)
 {
-  char buf[sizeof(int)];
+  char buf[sizeof(int)]; // { dg-message "region created on stack here" }
   int *p = new(buf) int (42);
-  delete p; // { dg-warning "memory not on the heap" }
+  delete p; // { dg-warning "memory on the stack" }
 }
 
 // { dg-prune-output "-Wfree-nonheap-object" }
diff --git a/gcc/testsuite/g++.dg/analyzer/pr100244.C b/gcc/testsuite/g++.dg/analyzer/pr100244.C
index 261b3cf..1d5e13d 100644
--- a/gcc/testsuite/g++.dg/analyzer/pr100244.C
+++ b/gcc/testsuite/g++.dg/analyzer/pr100244.C
@@ -11,7 +11,7 @@
   int _M_single_bucket;
   int *_M_buckets;
   _Hashtable_alloc () { _M_buckets = &_M_single_bucket; }
-  ~_Hashtable_alloc () { delete _M_buckets; } // { dg-warning "not on the heap" }
+  ~_Hashtable_alloc () { delete _M_buckets; } // { dg-warning "on the stack" }
 };
 
 void
diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c
index a9a2a3d..e956cf5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c
@@ -70,7 +70,7 @@
 void test_7 ()
 {
   struct foo f;
-  foo_release (&f); /* { dg-warning "not on the heap" "analyzer" } */
+  foo_release (&f); /* { dg-warning "on the stack" "analyzer" } */
   /* { dg-warning "'foo_release' called on unallocated object 'f'" "non-analyzer" { target *-*-* } .-1 } */
 }
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index 3219f85..d69a605 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -271,23 +271,23 @@
 
 int test_24 (void)
 {
-  void *ptr = __builtin_alloca (sizeof (int)); /* { dg-message "memory is allocated on the stack here" } */
-  free (ptr); /* { dg-warning "'free' of memory allocated on the stack by 'alloca' \\('ptr'\\) will corrupt the heap \\\[CWE-590\\\]" } */
+  void *ptr = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */
+  free (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack \\\[CWE-590\\\]" } */
 }
 
 int test_25 (void)
 {
-  char tmp[100];
-  void *p = tmp; /* { dg-message "pointer is from here" } */
-  free (p); /* { dg-warning "'free' of 'p' which points to memory not on the heap \\\[CWE-590\\\]" } */
+  char tmp[100]; /* { dg-message "region created on stack here" } */
+  void *p = tmp;
+  free (p); /* { dg-warning "'free' of 'p' which points to memory on the stack \\\[CWE-590\\\]" } */
   /* TODO: more precise messages here.  */
 }
 
-char global_buffer[100];
+char global_buffer[100]; /* { dg-message "region created here" } */
 
 int test_26 (void)
 {
-  void *p = global_buffer; /* { dg-message "pointer is from here" } */
+  void *p = global_buffer;
   free (p); /* { dg-warning "'free' of 'p' which points to memory not on the heap \\\[CWE-590\\\]" } */
   /* TODO: more precise messages here.  */
 }
@@ -608,4 +608,22 @@
   return x;
 }
 
+/* Free of function, and of label within function.  */
+
+void test_50a (void)
+{
+}
+
+void test_50b (void)
+{
+  free (test_50a); /* { dg-warning "'free' of '&test_50a' which points to memory not on the heap \\\[CWE-590\\\]" } */
+}
+
+void test_50c (void)
+{
+ my_label:
+  free (&&my_label); /* { dg-warning "'free' of '&my_label' which points to memory not on the heap \\\[CWE-590\\\]" } */
+}
+
+
 /* { dg-prune-output "\\\[-Wfree-nonheap-object" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c
index 8820ddd..c79f80d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c
@@ -61,9 +61,8 @@
 {
   allocator_t alloc_fn = get_alloca ();
   deallocator_t dealloc_fn = get_free ();
-  int *ptr = alloc_fn (sizeof (int)); /* { dg-message "pointer is from here" } */
-  /* TODO: message should read "memory is allocated on the stack here".  */
-  dealloc_fn (ptr); /* { dg-warning "'free' of 'ptr' which points to memory not on the heap" } */
+  int *ptr = alloc_fn (sizeof (int)); /* dg-message "region created on stack here" } */
+  dealloc_fn (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack" } */
 }
 
 static void __attribute__((noinline))
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c
index 9a7c414..4988f53 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c
@@ -40,7 +40,7 @@
 {
   void *ptr;
   if (sz <= LIMIT)
-    ptr = __builtin_alloca (sz); /* { dg-message "memory is allocated on the stack here" } */
+    ptr = __builtin_alloca (sz); /* { dg-message "region created on stack here" } */
   else
     ptr = malloc (sz);
 
@@ -49,7 +49,7 @@
   /* Bug: the "sz <= LIMIT" above should have been "sz < LIMIT",
      so there's a free-of-alloca when sz == LIMIT.  */
   if (sz >= LIMIT)
-    free (ptr); /* { dg-warning "'free' of memory allocated on the stack by 'alloca'" } */
+    free (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack" } */
 }
 /* { dg-bogus "leak of 'ptr'" } */
 /* This can't happen, as "sz > 1024" && "sz <= 1023" is impossible.  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104560-1.c b/gcc/testsuite/gcc.dg/analyzer/pr104560-1.c
new file mode 100644
index 0000000..aeab4b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104560-1.c
@@ -0,0 +1,43 @@
+/* Reduced/adapted from false positive from -Wanalyzer-free-of-non-heap
+   seen on rdma-core.  */
+
+#include <stddef.h>
+
+#define check_types_match(expr1, expr2)			\
+	((typeof(expr1) *)0 != (typeof(expr2) *)0)
+
+#define container_of(member_ptr, containing_type, member)		\
+	 ((containing_type *)						\
+	  ((char *)(member_ptr)						\
+	   - container_off(containing_type, member))			\
+	  + check_types_match(*(member_ptr), ((containing_type *)0)->member))
+
+#define container_off(containing_type, member)	\
+	offsetof(containing_type, member)
+
+struct ibv_device {
+	/* [...snip...] */
+};
+
+struct verbs_device {
+	struct ibv_device device; /* Must be first */
+	/* [...snip...] */
+	int placeholder;
+};
+
+struct mlx5_device {
+	struct verbs_device verbs_dev;
+	int placeholder;
+};
+
+static inline struct mlx5_device *to_mdev(struct ibv_device *ibdev)
+{
+	return container_of(ibdev, struct mlx5_device, verbs_dev.device);
+}
+  
+static void mlx5_uninit_device(struct verbs_device *verbs_device)
+{
+        struct mlx5_device *dev = to_mdev(&verbs_device->device);
+
+        __builtin_free(dev); /* { dg-bogus "not on the heap" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104560-2.c b/gcc/testsuite/gcc.dg/analyzer/pr104560-2.c
new file mode 100644
index 0000000..f968a58
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104560-2.c
@@ -0,0 +1,26 @@
+struct ibv_device {
+  /* [...snip...] */
+  int placeholder;
+};
+
+struct verbs_device {
+  struct ibv_device device; /* Must be first */
+  /* [...snip...] */
+  int placeholder;
+};
+
+struct mlx5_device {
+  struct verbs_device verbs_dev;
+  int placeholder;
+};
+
+static inline struct mlx5_device *to_mdev(struct ibv_device *ibdev)
+{
+  return (struct mlx5_device *)ibdev;
+}
+  
+static void mlx5_uninit_device(struct verbs_device *verbs_device)
+{
+  struct mlx5_device *dev = to_mdev(&verbs_device->device);
+  __builtin_free(dev); /* { dg-bogus "not on the heap" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c
index ef117ad..9951e11 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c
@@ -59,8 +59,8 @@
 
 void *test_7 (size_t sz)
 {
-  char buf[100];
-  void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '&buf' which points to memory not on the heap" } */
+  char buf[100]; /* { dg-message "region created on stack here" } */
+  void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '&buf' which points to memory on the stack" } */
   return p;  
 }
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c
new file mode 100644
index 0000000..a73289c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c
@@ -0,0 +1,134 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+int foo ()
+{
+  static volatile int v = 42;
+  int __result_foo;
+
+  __result_foo = (int) v;
+  return __result_foo;
+}
+
+void test (int * restrict n, int * restrict flag)
+{
+  int i;
+  int j;
+  int k;
+  double t;
+  int tt;
+  double v;
+
+  if (*flag)
+    {
+      t = 4.2e+1;
+      tt = foo ();
+    }
+  L_1: ;
+  v = 0.0;
+  {
+    int D_3353;
+
+    D_3353 = *n;
+    i = 1;
+    if (i <= D_3353)
+      {
+        while (1)
+          {
+            {
+              int D_3369;
+
+              v = 0.0;
+              if (*flag)
+                {
+                  if (tt == i)
+                    {
+                      {
+                        double M_0;
+
+                        M_0 = v;
+                        if (t > M_0 || (int) (M_0 != M_0))
+                          {
+                            M_0 = t;
+                          }
+                        v = M_0;
+                      }
+                    }
+                  L_5:;
+                }
+              L_4:;
+              {
+                int D_3359;
+
+                D_3359 = *n;
+                j = 1;
+                if (j <= D_3359)
+                  {
+                    while (1)
+                      {
+                        {
+                          int D_3368;
+
+                          {
+                            int D_3362;
+
+                            D_3362 = *n;
+                            k = 1;
+                            if (k <= D_3362)
+                              {
+                                while (1)
+                                  {
+                                    {
+                                      int D_3367;
+
+                                      {
+                                        double D_3366;
+                                        double M_1;
+
+                                        M_1 = v;
+                                        D_3366 = (double) __builtin_sinf ((float) (j * k));
+                                        if (D_3366 > M_1 || (int) (M_1 != M_1))
+                                          {
+                                            M_1 = D_3366;
+                                          }
+                                        v = M_1;
+                                      }
+                                      L_8:;
+                                      D_3367 = k == D_3362;
+                                      k = k + 1;
+                                      if (D_3367) goto L_9;
+                                    }
+                                  }
+                              }
+                            L_9:;
+                          }
+                          L_6:;
+                          D_3368 = j == D_3359;
+                          j = j + 1;
+                          if (D_3368) goto L_7;
+                        }
+                      }
+                  }
+                L_7:;
+              }
+              L_2:;
+              D_3369 = i == D_3353;
+              i = i + 1;
+              if (D_3369) goto L_3;
+            }
+          }
+      }
+    L_3:;
+  }
+}
+
+
+int main ()
+{
+  int flag;
+  int n;
+
+  n = 4;
+  flag = 0;
+  test (&n, &flag);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c
new file mode 100644
index 0000000..0b59acd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c
@@ -0,0 +1,16 @@
+float
+test_1 (int *flag, float theta)
+{
+  float t;
+  float f;
+
+  if (*flag)
+    t = 2.0f;
+
+  f = __builtin_sinf (theta);
+  
+  if (*flag)
+    f *= t;
+
+  return f;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/vla-1.c b/gcc/testsuite/gcc.dg/analyzer/vla-1.c
index e5971c8..9561d74 100644
--- a/gcc/testsuite/gcc.dg/analyzer/vla-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/vla-1.c
@@ -12,3 +12,12 @@
   s.b = 17;
   __analyzer_eval (s.b == 17); /* { dg-warning "TRUE" } */
 }
+
+void test_2 (int n)
+{
+  int arr[n]; /* { dg-message "region created on stack here" } */
+  __builtin_free (arr); /* { dg-warning "'free' of '<unknown>' which points to memory on the stack" } */
+  // TODO: fix the "unknown" here
+}
+
+/* { dg-prune-output "\\\[-Wfree-nonheap-object" } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99708.c b/gcc/testsuite/gcc.target/powerpc/pr99708.c
new file mode 100644
index 0000000..d478f7bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr99708.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { require-effective-target ppc_float128_sw } */
+/* { dg-options "-O2 -mvsx -mfloat128" } */
+
+/*
+ * PR target/99708
+ *
+ * Verify that __SIZEOF_FLOAT128__ and __SIZEOF_IBM128__ are properly defined.
+ */
+
+#include <stdlib.h>
+
+int main (void)
+{
+  if (__SIZEOF_FLOAT128__ != sizeof (__float128)
+      || __SIZEOF_IBM128__ != sizeof (__ibm128))
+    abort ();
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 b/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90
new file mode 100644
index 0000000..34cc25d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90
@@ -0,0 +1,39 @@
+! { dg-additional-options "-O0" }
+
+MODULE M1
+  IMPLICIT NONE
+CONTAINS
+  INTEGER FUNCTION foo()
+     INTEGER, VOLATILE :: v=42
+     foo=v
+  END FUNCTION
+  SUBROUTINE test(n,flag)
+    INTEGER :: n,i,j,k,l,tt
+    LOGICAL :: flag
+    REAL(KIND=8) :: v,t
+    IF (flag) THEN
+      t=42
+      tt=foo()
+    ENDIF
+    v=0
+    DO i=1,n
+       v=0
+       IF (flag) THEN
+          IF (tt==i) v=MAX(v,t)
+       ENDIF
+       DO j=1,n
+        DO k=1,n
+            v=MAX(v,sin(REAL(j*k)))
+         ENDDO
+       ENDDO
+    ENDDO
+  END SUBROUTINE
+END MODULE M1
+
+USE M1
+INTEGER :: n
+LOGICAL :: flag
+n=4
+flag=.FALSE.
+CALL test(n,flag)
+END
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index c77fe7a..e857dfc 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,7 @@
+2022-02-16  Ian Lance Taylor  <iant@golang.org>
+
+	* dwarf.c (build_address_map): Initialize DWARF 5 fields of unit.
+
 2022-02-03  David Seifert  <soap@gentoo.org>
 	    Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 2158bc1..45cc9e7 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -1989,14 +1989,16 @@
 	      break;
 
 	    case DW_AT_stmt_list:
-	      if (abbrev->tag == DW_TAG_compile_unit
+	      if ((abbrev->tag == DW_TAG_compile_unit
+		   || abbrev->tag == DW_TAG_skeleton_unit)
 		  && (val.encoding == ATTR_VAL_UINT
 		      || val.encoding == ATTR_VAL_REF_SECTION))
 		u->lineoff = val.u.uint;
 	      break;
 
 	    case DW_AT_name:
-	      if (abbrev->tag == DW_TAG_compile_unit)
+	      if (abbrev->tag == DW_TAG_compile_unit
+		  || abbrev->tag == DW_TAG_skeleton_unit)
 		{
 		  name_val = val;
 		  have_name_val = 1;
@@ -2004,7 +2006,8 @@
 	      break;
 
 	    case DW_AT_comp_dir:
-	      if (abbrev->tag == DW_TAG_compile_unit)
+	      if (abbrev->tag == DW_TAG_compile_unit
+		  || abbrev->tag == DW_TAG_skeleton_unit)
 		{
 		  comp_dir_val = val;
 		  have_comp_dir_val = 1;
@@ -2012,19 +2015,22 @@
 	      break;
 
 	    case DW_AT_str_offsets_base:
-	      if (abbrev->tag == DW_TAG_compile_unit
+	      if ((abbrev->tag == DW_TAG_compile_unit
+		   || abbrev->tag == DW_TAG_skeleton_unit)
 		  && val.encoding == ATTR_VAL_REF_SECTION)
 		u->str_offsets_base = val.u.uint;
 	      break;
 
 	    case DW_AT_addr_base:
-	      if (abbrev->tag == DW_TAG_compile_unit
+	      if ((abbrev->tag == DW_TAG_compile_unit
+		   || abbrev->tag == DW_TAG_skeleton_unit)
 		  && val.encoding == ATTR_VAL_REF_SECTION)
 		u->addr_base = val.u.uint;
 	      break;
 
 	    case DW_AT_rnglists_base:
-	      if (abbrev->tag == DW_TAG_compile_unit
+	      if ((abbrev->tag == DW_TAG_compile_unit
+		   || abbrev->tag == DW_TAG_skeleton_unit)
 		  && val.encoding == ATTR_VAL_REF_SECTION)
 		u->rnglists_base = val.u.uint;
 	      break;
@@ -2052,7 +2058,8 @@
 	}
 
       if (abbrev->tag == DW_TAG_compile_unit
-	  || abbrev->tag == DW_TAG_subprogram)
+	  || abbrev->tag == DW_TAG_subprogram
+	  || abbrev->tag == DW_TAG_skeleton_unit)
 	{
 	  if (!add_ranges (state, dwarf_sections, base_address,
 			   is_bigendian, u, pcrange.lowpc, &pcrange,
@@ -2060,9 +2067,10 @@
 			   (void *) addrs))
 	    return 0;
 
-	  /* If we found the PC range in the DW_TAG_compile_unit, we
-	     can stop now.  */
-	  if (abbrev->tag == DW_TAG_compile_unit
+	  /* If we found the PC range in the DW_TAG_compile_unit or
+	     DW_TAG_skeleton_unit, we can stop now.  */
+	  if ((abbrev->tag == DW_TAG_compile_unit
+	       || abbrev->tag == DW_TAG_skeleton_unit)
 	      && (pcrange.have_ranges
 		  || (pcrange.have_lowpc && pcrange.have_highpc)))
 	    return 1;
@@ -3274,7 +3282,8 @@
 
 	  /* The compile unit sets the base address for any address
 	     ranges in the function entries.  */
-	  if (abbrev->tag == DW_TAG_compile_unit
+	  if ((abbrev->tag == DW_TAG_compile_unit
+	       || abbrev->tag == DW_TAG_skeleton_unit)
 	      && abbrev->attrs[i].name == DW_AT_low_pc)
 	    {
 	      if (val.encoding == ATTR_VAL_ADDRESS)
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog
index e329ffb1..5359674 100644
--- a/libphobos/ChangeLog
+++ b/libphobos/ChangeLog
@@ -1,3 +1,16 @@
+2022-02-16  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	* Makefile.in: Regenerate.
+	* libdruntime/MERGE: Merge upstream druntime dbd0c874.
+	* libdruntime/Makefile.am (DRUNTIME_CSOURCES): Add core/int128.d.
+	(DRUNTIME_DISOURCES): Add __builtins.di.
+	* libdruntime/Makefile.in: Regenerate.
+	* src/MERGE: Merge upstream phobos 896b1d0e1.
+	* src/Makefile.am (PHOBOS_DSOURCES): Add std/checkedint.d.
+	* src/Makefile.in: Regenerate.
+	* testsuite/testsuite_flags.in: Add -fall-instantiations to
+	--gdcflags.
+
 2022-01-03  Iain Buclaw  <ibuclaw@gdcproject.org>
 
 	* libdruntime/MERGE: Merge upstream druntime 759e6023.