# DP: updates from the gcc-10 branch upto 20220718 (142b66f30d1).

LANG=C git diff --no-renames --src-prefix=a/src/ --dst-prefix=b/src/ \
	7ff47281ce4f3699185b06a3430968eac2a5b0c6 142b66f30d1ef9b7fbaf7833e5bf3e14bbccd0d3 \
	| awk '/^diff .*\.texi/ {skip=1; next} /^diff / { skip=0 } skip==0' \
	| grep -v -E '^(diff|index)'

--- a/src/gcc/ChangeLog
+++ b/src/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2022-07-13  Martin Jambor  <mjambor@suse.cz>
+
+	Backported from master:
+	2022-07-04  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/105860
+	* tree-sra.c (build_reconstructed_reference): Start expr
+	traversal only just below the outermost union.
+
 2022-06-28  Release Manager
 
 	* GCC 10.4.0 released.
--- a/src/gcc/DATESTAMP
+++ b/src/gcc/DATESTAMP
@@ -1 +1 @@
-20220628
+20220718
--- a/src/gcc/d/ChangeLog
+++ b/src/gcc/d/ChangeLog
@@ -1,3 +1,18 @@
+2022-07-05  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	Backported from master:
+	2022-07-04  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	PR d/106139
+	* d-convert.cc (convert_expr): Handle casting from array to vector.
+	(convert_for_rvalue): Rewrite vector to array casts of the same
+	element type into a constructor.
+	(convert_for_assignment): Return calling convert_for_rvalue.
+	* dmd/expressionsem.c (ExpressionSemanticVisitor::visit): Run semantic
+	on vector expression after lowering.
+	* expr.cc (ExprVisitor::visit (VectorExp *)): Handle generating a
+	vector expression from a static array.
+
 2022-06-28  Release Manager
 
 	* GCC 10.4.0 released.
--- a/src/gcc/d/d-convert.cc
+++ b/src/gcc/d/d-convert.cc
@@ -502,6 +502,15 @@ convert_expr (tree exp, Type *etype, Type *totype)
 	  gcc_assert (totype->size () == etype->size ());
 	  result = build_vconvert (build_ctype (totype), exp);
 	}
+      else if (tbtype->ty == Tvector && tbtype->size () == ebtype->size ())
+	{
+	  /* Allow casting from array to vector as if its an unaligned load.  */
+	  tree type = build_ctype (totype);
+	  tree unaligned_type = build_variant_type_copy (type);
+	  SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
+	  TYPE_USER_ALIGN (unaligned_type) = 1;
+	  result = convert (type, build_vconvert (unaligned_type, exp));
+	}
       else
 	{
 	  error ("cannot cast expression of type %qs to type %qs",
@@ -634,6 +643,39 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
       break;
     }
 
+  if (tbtype->ty == Tsarray
+      && ebtype->ty == Tsarray
+      && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
+      && INDIRECT_REF_P (expr)
+      && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
+      && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
+    {
+      /* If expression is a vector that was casted to an array either by
+	 explicit type cast or by taking the vector's `.array' value, strip the
+	 reinterpret cast and build a constructor instead.  */
+      tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+
+      if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
+	{
+	  /* Rewrite: `*(Array *)&vector'
+		into: `{ vector[0], vector[1], ... }'  */
+	  tree array = d_save_expr (TREE_OPERAND (ptr, 0));
+	  array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
+
+	  uinteger_t dim = ((TypeSArray *)tbtype)->dim->toUInteger ();
+	  vec <constructor_elt, va_gc> *elms = NULL;
+	  for (uinteger_t i = 0; i < dim; i++)
+	    {
+	      tree index = size_int (i);
+	      tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
+				   array, index, NULL_TREE, NULL_TREE);
+	      CONSTRUCTOR_APPEND_ELT (elms, index, value);
+	    }
+
+	  return build_constructor (build_ctype (totype), elms);
+	}
+    }
+
   return result ? result : convert_expr (expr, etype, totype);
 }
 
@@ -694,7 +736,7 @@ convert_for_assignment (tree expr, Type *etype, Type *totype)
       return expr;
     }
 
-  return convert_expr (expr, etype, totype);
+  return convert_for_rvalue (expr, etype, totype);
 }
 
 /* Return a TREE representation of EXPR converted to represent
--- a/src/gcc/d/dmd/expressionsem.c
+++ b/src/gcc/d/dmd/expressionsem.c
@@ -4309,6 +4309,7 @@ public:
         if (tob->ty == Tvector && t1b->ty != Tvector)
         {
             result = new VectorExp(exp->loc, exp->e1, exp->to);
+            result = semantic(result, sc);
             return;
         }
 
--- a/src/gcc/d/expr.cc
+++ b/src/gcc/d/expr.cc
@@ -2993,21 +2993,20 @@ public:
 
   void visit (VectorExp *e)
   {
-    tree type = build_ctype (e->type);
-    tree etype = TREE_TYPE (type);
-
     /* First handle array literal expressions.  */
     if (e->e1->op == TOKarrayliteral)
       {
 	ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
 	vec<constructor_elt, va_gc> *elms = NULL;
 	bool constant_p = true;
+	tree type = build_ctype (e->type);
 
 	vec_safe_reserve (elms, ale->elements->dim);
 	for (size_t i = 0; i < ale->elements->dim; i++)
 	  {
 	    Expression *expr = ale->getElement (i);
-	    tree value = d_convert (etype, build_expr (expr, this->constp_));
+	    tree value = d_convert (TREE_TYPE (type),
+				    build_expr (expr, this->constp_));
 	    if (!CONSTANT_CLASS_P (value))
 	      constant_p = false;
 
@@ -3020,10 +3019,18 @@ public:
 	else
 	  this->result_ = build_constructor (type, elms);
       }
+    else if (e->e1->type->toBasetype ()->ty == Tsarray)
+      {
+	/* Build a vector representation from a static array.  */
+	this->result_ = convert_expr (build_expr (e->e1, this->constp_),
+				      e->e1->type, e->type);
+      }
     else
       {
 	/* Build constructor from single value.  */
-	tree val = d_convert (etype, build_expr (e->e1, this->constp_));
+	tree type = build_ctype (e->type);
+	tree val = d_convert (TREE_TYPE (type),
+			      build_expr (e->e1, this->constp_));
 	this->result_ = build_vector_from_val (type, val);
       }
   }
--- a/src/gcc/fortran/ChangeLog
+++ b/src/gcc/fortran/ChangeLog
@@ -1,3 +1,66 @@
+2022-07-16  Steve Kargl  <kargl@gcc.gnu.org>
+
+	Backported from master:
+	2022-07-15  Steve Kargl  <kargl@gcc.gnu.org>
+
+	PR fortran/104313
+	* trans-decl.c (gfc_generate_return): Do not generate conflicting
+	fake results for functions with no result variable under -ff2c.
+
+2022-07-03  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-30  Harald Anlauf  <anlauf@gmx.de>
+		    Steven G. Kargl  <kargl@gcc.gnu.org>
+
+	PR fortran/103137
+	PR fortran/103138
+	PR fortran/103693
+	PR fortran/105243
+	* decl.c (gfc_match_data_decl): Reject CLASS entity declaration
+	when it is given the PARAMETER attribute.
+
+2022-07-03  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-29  Harald Anlauf  <anlauf@gmx.de>
+		    Steven G. Kargl  <kargl@gcc.gnu.org>
+
+	PR fortran/106121
+	* simplify.c (gfc_simplify_extends_type_of): Do not attempt to
+	simplify when one of the arguments is a CLASS variable that was
+	not properly declared.
+
+2022-07-01  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-26  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105954
+	* decl.c (variable_decl): Adjust upper bounds for explicit-shape
+	specs with constant bound expressions to ensure non-negative
+	extents.
+
+2022-07-01  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-26  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105691
+	* simplify.c (gfc_simplify_index): Replace old simplification
+	code by the equivalent of the runtime library implementation.  Use
+	HOST_WIDE_INT instead of int for string index, length variables.
+
+2022-07-01  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-24  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105813
+	* check.c (gfc_check_unpack): Try to simplify MASK argument to
+	UNPACK so that checking of the VECTOR argument can work when MASK
+	is a variable.
+
 2022-06-28  Release Manager
 
 	* GCC 10.4.0 released.
--- a/src/gcc/fortran/check.c
+++ b/src/gcc/fortran/check.c
@@ -6329,6 +6329,8 @@ gfc_check_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
   if (!same_type_check (vector, 0, field, 2))
     return false;
 
+  gfc_simplify_expr (mask, 0);
+
   if (mask->expr_type == EXPR_ARRAY
       && gfc_array_size (vector, &vector_size))
     {
--- a/src/gcc/fortran/decl.c
+++ b/src/gcc/fortran/decl.c
@@ -2685,6 +2685,18 @@ variable_decl (int elem)
 		  else
 		    gfc_free_expr (n);
 		}
+	      /* For an explicit-shape spec with constant bounds, ensure
+		 that the effective upper bound is not lower than the
+		 respective lower bound minus one.  Otherwise adjust it so
+		 that the extent is trivially derived to be zero.  */
+	      if (as->lower[i]->expr_type == EXPR_CONSTANT
+		  && as->upper[i]->expr_type == EXPR_CONSTANT
+		  && as->lower[i]->ts.type == BT_INTEGER
+		  && as->upper[i]->ts.type == BT_INTEGER
+		  && mpz_cmp (as->upper[i]->value.integer,
+			      as->lower[i]->value.integer) < 0)
+		mpz_sub_ui (as->upper[i]->value.integer,
+			    as->lower[i]->value.integer, 1);
 	    }
 	}
     }
@@ -6169,6 +6181,14 @@ gfc_match_data_decl (void)
       goto cleanup;
     }
 
+  /* F2018:C708.  */
+  if (current_ts.type == BT_CLASS && current_attr.flavor == FL_PARAMETER)
+    {
+      gfc_error ("CLASS entity at %C cannot have the PARAMETER attribute");
+      m = MATCH_ERROR;
+      goto cleanup;
+    }
+
   if (current_ts.type == BT_CLASS
 	&& current_ts.u.derived->attr.unlimited_polymorphic)
     goto ok;
--- a/src/gcc/fortran/simplify.c
+++ b/src/gcc/fortran/simplify.c
@@ -3060,6 +3060,10 @@ gfc_simplify_extends_type_of (gfc_expr *a, gfc_expr *mold)
   if (UNLIMITED_POLY (a) || UNLIMITED_POLY (mold))
     return NULL;
 
+  if ((a->ts.type == BT_CLASS && !gfc_expr_attr (a).class_ok)
+      || (mold->ts.type == BT_CLASS && !gfc_expr_attr (mold).class_ok))
+    return NULL;
+
   /* Return .false. if the dynamic type can never be an extension.  */
   if ((a->ts.type == BT_CLASS && mold->ts.type == BT_CLASS
        && !gfc_type_is_extension_of
@@ -3470,17 +3474,15 @@ gfc_expr *
 gfc_simplify_index (gfc_expr *x, gfc_expr *y, gfc_expr *b, gfc_expr *kind)
 {
   gfc_expr *result;
-  int back, len, lensub;
-  int i, j, k, count, index = 0, start;
+  bool back;
+  HOST_WIDE_INT len, lensub, start, last, i, index = 0;
+  int k, delta;
 
   if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT
       || ( b != NULL && b->expr_type !=  EXPR_CONSTANT))
     return NULL;
 
-  if (b != NULL && b->value.logical != 0)
-    back = 1;
-  else
-    back = 0;
+  back = (b != NULL && b->value.logical != 0);
 
   k = get_kind (BT_INTEGER, kind, "INDEX", gfc_default_integer_kind);
   if (k == -1)
@@ -3497,111 +3499,40 @@ gfc_simplify_index (gfc_expr *x, gfc_expr *y, gfc_expr *b, gfc_expr *kind)
       return result;
     }
 
-  if (back == 0)
+  if (lensub == 0)
     {
-      if (lensub == 0)
-	{
-	  mpz_set_si (result->value.integer, 1);
-	  return result;
-	}
-      else if (lensub == 1)
-	{
-	  for (i = 0; i < len; i++)
-	    {
-	      for (j = 0; j < lensub; j++)
-		{
-		  if (y->value.character.string[j]
-		      == x->value.character.string[i])
-		    {
-		      index = i + 1;
-		      goto done;
-		    }
-		}
-	    }
-	}
+      if (back)
+	index = len + 1;
       else
-	{
-	  for (i = 0; i < len; i++)
-	    {
-	      for (j = 0; j < lensub; j++)
-		{
-		  if (y->value.character.string[j]
-		      == x->value.character.string[i])
-		    {
-		      start = i;
-		      count = 0;
-
-		      for (k = 0; k < lensub; k++)
-			{
-			  if (y->value.character.string[k]
-			      == x->value.character.string[k + start])
-			    count++;
-			}
-
-		      if (count == lensub)
-			{
-			  index = start + 1;
-			  goto done;
-			}
-		    }
-		}
-	    }
-	}
+	index = 1;
+      goto done;
+    }
 
+  if (!back)
+    {
+      last = len + 1 - lensub;
+      start = 0;
+      delta = 1;
     }
   else
     {
-      if (lensub == 0)
-	{
-	  mpz_set_si (result->value.integer, len + 1);
-	  return result;
-	}
-      else if (lensub == 1)
+      last = -1;
+      start = len - lensub;
+      delta = -1;
+    }
+
+  for (; start != last; start += delta)
+    {
+      for (i = 0; i < lensub; i++)
 	{
-	  for (i = 0; i < len; i++)
-	    {
-	      for (j = 0; j < lensub; j++)
-		{
-		  if (y->value.character.string[j]
-		      == x->value.character.string[len - i])
-		    {
-		      index = len - i + 1;
-		      goto done;
-		    }
-		}
-	    }
+	  if (x->value.character.string[start + i]
+	      != y->value.character.string[i])
+	    break;
 	}
-      else
+      if (i == lensub)
 	{
-	  for (i = 0; i < len; i++)
-	    {
-	      for (j = 0; j < lensub; j++)
-		{
-		  if (y->value.character.string[j]
-		      == x->value.character.string[len - i])
-		    {
-		      start = len - i;
-		      if (start <= len - lensub)
-			{
-			  count = 0;
-			  for (k = 0; k < lensub; k++)
-			    if (y->value.character.string[k]
-			        == x->value.character.string[k + start])
-			      count++;
-
-			  if (count == lensub)
-			    {
-			      index = start + 1;
-			      goto done;
-			    }
-			}
-		      else
-			{
-			  continue;
-			}
-		    }
-		}
-	    }
+	  index = start + 1;
+	  goto done;
 	}
     }
 
--- a/src/gcc/fortran/trans-decl.c
+++ b/src/gcc/fortran/trans-decl.c
@@ -6545,7 +6545,7 @@ gfc_generate_return (void)
 	     NULL_TREE, and a 'return' is generated without a variable.
 	     The following generates a 'return __result_XXX' where XXX is
 	     the function name.  */
-	  if (sym == sym->result && sym->attr.function)
+	  if (sym == sym->result && sym->attr.function && !flag_f2c)
 	    {
 	      result = gfc_get_fake_result_decl (sym, 0);
 	      result = fold_build2_loc (input_location, MODIFY_EXPR,
--- a/src/gcc/testsuite/ChangeLog
+++ b/src/gcc/testsuite/ChangeLog
@@ -1,3 +1,78 @@
+2022-07-16  Steve Kargl  <kargl@gcc.gnu.org>
+
+	Backported from master:
+	2022-07-15  Steve Kargl  <kargl@gcc.gnu.org>
+
+	PR fortran/104313
+	* gfortran.dg/pr104313.f: New test.
+
+2022-07-13  Martin Jambor  <mjambor@suse.cz>
+
+	Backported from master:
+	2022-07-04  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/105860
+	* gcc.dg/tree-ssa/alias-access-path-13.c: New test.
+	* gcc.dg/tree-ssa/pr105860.c: Likewise.
+
+2022-07-05  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	Backported from master:
+	2022-07-04  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	PR d/106139
+	* gdc.dg/pr106139a.d: New test.
+	* gdc.dg/pr106139b.d: New test.
+	* gdc.dg/pr106139c.d: New test.
+	* gdc.dg/pr106139d.d: New test.
+	* gdc.test/fail_compilation/ice20264.d: New test.
+
+2022-07-03  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-30  Harald Anlauf  <anlauf@gmx.de>
+		    Steven G. Kargl  <kargl@gcc.gnu.org>
+
+	PR fortran/103137
+	PR fortran/103138
+	PR fortran/103693
+	PR fortran/105243
+	* gfortran.dg/class_58.f90: Fix test.
+	* gfortran.dg/class_73.f90: New test.
+
+2022-07-03  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-29  Harald Anlauf  <anlauf@gmx.de>
+		    Steven G. Kargl  <kargl@gcc.gnu.org>
+
+	PR fortran/106121
+	* gfortran.dg/extends_type_of_4.f90: New test.
+
+2022-07-01  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-26  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105954
+	* gfortran.dg/pr105954.f90: New test.
+
+2022-07-01  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-26  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105691
+	* gfortran.dg/index_6.f90: New test.
+
+2022-07-01  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2022-06-24  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105813
+	* gfortran.dg/unpack_vector_1.f90: New test.
+
 2022-06-28  Release Manager
 
 	* GCC 10.4.0 released.
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+struct inn
+{
+  int val;
+};
+
+struct biggerstruct
+{
+  int a, b;
+};
+
+union foo
+{
+  struct inn inn;
+  struct biggerstruct baz;
+} *fooptr;
+
+struct bar
+{
+  union foo foo;
+  int val2;
+} *barptr;
+
+int
+test ()
+{
+  union foo foo;
+  foo.inn.val = 0;
+  barptr->val2 = 123;
+  *fooptr = foo;
+  return barptr->val2;
+}
+
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c
@@ -0,0 +1,63 @@
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+struct S1  {
+        unsigned int _0;
+        unsigned int _1;
+} ;
+struct S2  {
+        struct S1 _s1;
+        unsigned long _x2;
+} ;
+
+struct ufld_type1  {
+        unsigned int _u1t;
+        struct S2 _s2;
+} ;
+
+struct ufld_type2  {
+        unsigned int _u2t;
+        struct S1 _s1;
+} ;
+struct parm_type {
+        union {
+                struct ufld_type1 var_1;
+                struct ufld_type2 var_2;
+        } U;
+};
+
+struct parm_type  bad_function( struct parm_type arg0 )
+{
+        struct parm_type rv;
+        struct S2 var4;
+        switch( arg0.U.var_2._u2t ) {
+        case 4294967041:
+                var4._s1 = arg0.U.var_1._s2._s1;
+                rv.U.var_1._u1t = 4294967041;
+                rv.U.var_1._s2 = var4;
+                break;
+        case 4294967043:
+                rv.U.var_2._u2t = 4294967043;
+                rv.U.var_2._s1 = arg0.U.var_2._s1;
+                break;
+        default:
+                break;
+        }
+        return rv;
+}
+
+int main() {
+        struct parm_type val;
+        struct parm_type out;
+        val.U.var_2._u2t = 4294967043;
+        val.U.var_2._s1._0 = 0x01010101;
+        val.U.var_2._s1._1 = 0x02020202;
+        out = bad_function(val);
+	if (val.U.var_2._u2t != 4294967043)
+	  __builtin_abort ();
+        if (out.U.var_2._s1._0 != 0x01010101)
+	  __builtin_abort ();
+        if (val.U.var_2._s1._1 != 0x02020202 )
+	  __builtin_abort ();
+	return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gdc.dg/pr106139a.d
@@ -0,0 +1,36 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias A = int[4];
+
+static if (__traits(compiles, __vector(A))):
+
+A vector2array(__vector(A) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(A) v)
+{
+    a = cast(A)v;
+}
+
+__vector(A) array2vector(A a)
+{
+    return cast(__vector(A)) a;
+}
+
+void array2vector(ref __vector(A) v, A a)
+{
+    v = cast(__vector(A))a;
+}
+
+A vector2array_array(__vector(A) v)
+{
+    return v.array;
+}
+
+void vector2array_array(ref A a, __vector(A) v)
+{
+    a = v.array;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gdc.dg/pr106139b.d
@@ -0,0 +1,36 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias A = float[4];
+
+static if (__traits(compiles, __vector(A))):
+
+A vector2array(__vector(A) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(A) v)
+{
+    a = cast(A)v;
+}
+
+__vector(A) array2vector(A a)
+{
+    return cast(__vector(A)) a;
+}
+
+void array2vector(ref __vector(A) v, A a)
+{
+    v = cast(__vector(A))a;
+}
+
+A vector2array_array(__vector(A) v)
+{
+    return v.array;
+}
+
+void vector2array_array(ref A a, __vector(A) v)
+{
+    a = v.array;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gdc.dg/pr106139c.d
@@ -0,0 +1,27 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias V = int[4];
+alias A = float[4];
+
+static if (__traits(compiles, __vector(V))):
+
+A vector2array(__vector(V) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(V) v)
+{
+    a = cast(A)v;
+}
+
+__vector(V) array2vector(A a)
+{
+    return cast(__vector(V)) a;
+}
+
+void array2vector(ref __vector(V) v, A a)
+{
+    v = cast(__vector(V))a;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gdc.dg/pr106139d.d
@@ -0,0 +1,27 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias V = float[4];
+alias A = int[4];
+
+static if (__traits(compiles, __vector(V))):
+
+A vector2array(__vector(V) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(V) v)
+{
+    a = cast(A)v;
+}
+
+__vector(V) array2vector(A a)
+{
+    return cast(__vector(V)) a;
+}
+
+void array2vector(ref __vector(V) v, A a)
+{
+    v = cast(__vector(V))a;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gdc.test/fail_compilation/ice20264.d
@@ -0,0 +1,13 @@
+/*
+DISABLED: freebsd32 linux32 osx32 win32
+TEST_OUTPUT:
+---
+fail_compilation/ice20264.d(12): Error: `cast(__vector(float[4]))a` is not an lvalue and cannot be modified
+---
+*/
+
+void foo(float *a)
+{
+    alias float4 = __vector(float[4]);
+    cast(float4)(a) = 1.0f;
+}
--- a/src/gcc/testsuite/gfortran.dg/class_58.f90
+++ b/src/gcc/testsuite/gfortran.dg/class_58.f90
@@ -9,5 +9,5 @@ subroutine s
   end type
   class(t), parameter :: x = t()  ! { dg-error "cannot have the PARAMETER attribute" }
   class(t), parameter :: y = x    ! { dg-error "cannot have the PARAMETER attribute" }
-  class(t) :: z = x               ! { dg-error "must be dummy, allocatable or pointer" }
+  class(t) :: z = t()             ! { dg-error "must be dummy, allocatable or pointer" }
 end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/class_73.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! Error recovery on invalid CLASS(), PARAMETER declarations
+! PR fortran/103137
+! PR fortran/103138
+! PR fortran/103693
+! PR fortran/105243
+! Contributed by G.Steinmetz
+
+program p
+  type t
+     character(3) :: c = '(a)'
+  end type
+  class(t), parameter :: x = 1.  ! { dg-error "PARAMETER attribute" }
+  class(*), parameter :: y = t() ! { dg-error "PARAMETER attribute" }
+  class(*), parameter :: z = 1   ! { dg-error "PARAMETER attribute" }
+  print x%c                      ! { dg-error "Syntax error" }
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/extends_type_of_4.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! PR fortran/106121 - ICE in gfc_simplify_extends_type_of
+! Contributed by G.Steinmetz
+
+program p
+   type t
+   end type
+   type(t)  :: x
+   class(t) :: y               ! { dg-error "dummy, allocatable or pointer" }
+   print *, extends_type_of (x, y)
+end
+
+subroutine s
+   type t
+      integer :: i
+   end type
+   type(t)  :: x
+   class(t) :: y               ! { dg-error "dummy, allocatable or pointer" }
+   stop extends_type_of (x, y) ! { dg-error "STOP code" }
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/index_6.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR fortran/105691 - Incorrect calculation of INDEX(str1,str2) at compile time
+
+program main
+  implicit none
+  integer :: i
+  character(*), parameter :: s1 = "fortran.f90"
+  character(*), parameter :: s2 = "fortran"
+  character(*), parameter :: s3 = s2 // "*"
+  integer, parameter :: i0    = index(s1, s2)
+  integer, parameter :: i1    = index(s1, s2, back= .true.)
+  integer, parameter :: i2(*) = index(s1, s2, back=[.true.,.false.])
+  integer, parameter :: i3(*) = index(s1, s2, back=[(i==1, i=1,2)] )
+  integer, parameter :: i4    = index(s1, s3)
+  integer, parameter :: i5    = index(s1, s3, back= .true.)
+  integer, parameter :: i6(*) = index(s1, s3, back=[.true.,.false.])
+  integer, parameter :: i7(*) = index(s1, s3, back=[(i==1, i=1,2)] )
+  integer, parameter :: i8    = index(s1, "f", back= .true.)
+  if (     i0 /= 1 ) stop 1
+  if (     i1 /= 1 ) stop 2
+  if (any (i2 /= 1)) stop 3
+  if (any (i3 /= 1)) stop 4
+  if (     i4 /= 0 ) stop 5
+  if (     i5 /= 0 ) stop 6
+  if (any (i6 /= 0)) stop 7
+  if (any (i7 /= 0)) stop 8
+  if (i8 /= len(s1)-2) stop 9
+end program
+
+! { dg-final { scan-tree-dump-not "_gfortran_stop_numeric" "original" } }
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/pr104313.f
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-additional-options "-ff2c -fdump-tree-original" }
+!
+! PR fortran/104313 - ICE verify_gimple failed with -ff2c
+! Contributed by G.Steinmetz
+
+      function f(a)
+      return
+      end
+
+! { dg-final { scan-tree-dump-times "return" 1 "original" } }
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/pr105954.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR fortran/105954 - ICE in gfc_element_size, at fortran/target-memory.cc:132
+! Contributed by G.Steinmetz
+
+program p
+  use iso_c_binding, only: c_float, c_sizeof
+  implicit none
+  integer, parameter :: n = -99
+  type t
+     real :: b(3,7:n)
+  end type
+  type, bind(c) :: u
+     real(c_float) :: b(3,7:n)
+  end type
+  type(t) :: d
+  type(u) :: e
+  integer, parameter :: k = storage_size(d)
+  integer, parameter :: m = sizeof(d)
+  integer, parameter :: l = c_sizeof(e)
+  if (k /= 0) stop 1
+  if (m /= 0) stop 2
+  if (l /= 0) stop 3
+end
+
+! { dg-final { scan-tree-dump-not "_gfortran_stop_numeric" "original" } }
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/unpack_vector_1.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! PR fortran/105813
+! Fix checking of VECTOR argument to UNPACK when MASK is a variable.
+! Contributed by G.Steinmetz
+
+program p
+  logical, parameter :: mask(2,2) = reshape ([.true.,  .true.,  &
+                                              .false., .true.], &
+                                              shape (mask))
+  print *, unpack ([1,2,3], mask, 0) ! OK
+  print *, unpack ([1,2],   mask, 0) ! { dg-error "must provide at least" }
+end
--- a/src/gcc/tree-sra.c
+++ b/src/gcc/tree-sra.c
@@ -1647,7 +1647,18 @@ build_ref_for_offset (location_t loc, tree base, poly_int64 offset,
 static tree
 build_reconstructed_reference (location_t, tree base, struct access *model)
 {
-  tree expr = model->expr, prev_expr = NULL;
+  tree expr = model->expr;
+  /* We have to make sure to start just below the outermost union.  */
+  tree start_expr = expr;
+  while (handled_component_p (expr))
+    {
+      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == UNION_TYPE)
+	start_expr = expr;
+      expr = TREE_OPERAND (expr, 0);
+    }
+
+  expr = start_expr;
+  tree prev_expr = NULL_TREE;
   while (!types_compatible_p (TREE_TYPE (expr), TREE_TYPE (base)))
     {
       if (!handled_component_p (expr))
