Submitted By:            Bruce Dubbs <bdubbs@liinuxfromscratch.org>
Date:                    2015-05-23
Initial Package Version: 5.1.0
Upstream Status:         Committed
Origin:                  https://patchwork.ozlabs.org/patch/469768/raw/ and
                         gcc git
Description:             Fix acc_device_type not distinguishing between
                         "offloaded" and host code with the host_nonshm plugin.
                         Fix inline issues.

commit adccf2e7d313263d585f63e752a4d36653d47811
Author: Julian Brown <julian@codesourcery.com>
Date:   Tue Apr 21 12:40:45 2015 -0700

    Non-SHM acc_on_device fixes

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6fe1456..5930fe4 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5917,6 +5917,7 @@ expand_stack_save (void)
 static rtx
 expand_builtin_acc_on_device (tree exp, rtx target)
 {
+#ifdef ACCEL_COMPILER
   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
     return NULL_RTX;
 
@@ -5925,13 +5926,8 @@ expand_builtin_acc_on_device (tree exp, rtx target)
   /* Return (arg == v1 || arg == v2) ? 1 : 0.  */
   machine_mode v_mode = TYPE_MODE (TREE_TYPE (arg));
   rtx v = expand_normal (arg), v1, v2;
-#ifdef ACCEL_COMPILER
   v1 = GEN_INT (GOMP_DEVICE_NOT_HOST);
   v2 = GEN_INT (ACCEL_COMPILER_acc_device);
-#else
-  v1 = GEN_INT (GOMP_DEVICE_NONE);
-  v2 = GEN_INT (GOMP_DEVICE_HOST);
-#endif
   machine_mode target_mode = TYPE_MODE (integer_type_node);
   if (!target || !register_operand (target, target_mode))
     target = gen_reg_rtx (target_mode);
@@ -5945,6 +5941,9 @@ expand_builtin_acc_on_device (tree exp, rtx target)
   emit_label (done_label);
 
   return target;
+#else
+  return NULL;
+#endif
 }
 
 
diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c
index 335ffd4..157147a 100644
--- a/libgomp/oacc-init.c
+++ b/libgomp/oacc-init.c
@@ -29,6 +29,7 @@
 #include "libgomp.h"
 #include "oacc-int.h"
 #include "openacc.h"
+#include "plugin/plugin-host.h"
 #include <assert.h>
 #include <stdlib.h>
 #include <strings.h>
@@ -611,11 +612,18 @@ ialias (acc_set_device_num)
 int
 acc_on_device (acc_device_t dev)
 {
-  if (acc_get_device_type () == acc_device_host_nonshm)
+  struct goacc_thread *thr = goacc_thread ();
+
+  /* We only want to appear to be the "host_nonshm" plugin from "offloaded"
+     code -- i.e. within a parallel region.  Test a flag set by the
+     openacc_parallel hook of the host_nonshm plugin to determine that.  */
+  if (acc_get_device_type () == acc_device_host_nonshm
+      && thr && thr->target_tls
+      && ((struct nonshm_thread *)thr->target_tls)->nonshm_exec)
     return dev == acc_device_host_nonshm || dev == acc_device_not_host;
 
-  /* Just rely on the compiler builtin.  */
-  return __builtin_acc_on_device (dev);
+  /* For OpenACC, libgomp is only built for the host, so this is sufficient.  */
+  return dev == acc_device_host || dev == acc_device_none;
 }
 
 ialias (acc_on_device)
diff --git a/libgomp/plugin/plugin-host.c b/libgomp/plugin/plugin-host.c
index 1faf5bc..3cb4dab 100644
--- a/libgomp/plugin/plugin-host.c
+++ b/libgomp/plugin/plugin-host.c
@@ -44,6 +44,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdbool.h>
 
 #ifdef HOST_NONSHM_PLUGIN
 #define STATIC
@@ -55,6 +56,10 @@
 #define SELF "host: "
 #endif
 
+#ifdef HOST_NONSHM_PLUGIN
+#include "plugin-host.h"
+#endif
+
 STATIC const char *
 GOMP_OFFLOAD_get_name (void)
 {
@@ -174,7 +179,10 @@ GOMP_OFFLOAD_openacc_parallel (void (*fn) (void *),
 			       void *targ_mem_desc __attribute__ ((unused)))
 {
 #ifdef HOST_NONSHM_PLUGIN
+  struct nonshm_thread *thd = GOMP_PLUGIN_acc_thread ();
+  thd->nonshm_exec = true;
   fn (devaddrs);
+  thd->nonshm_exec = false;
 #else
   fn (hostaddrs);
 #endif
@@ -232,11 +240,20 @@ STATIC void *
 GOMP_OFFLOAD_openacc_create_thread_data (int ord
 					 __attribute__ ((unused)))
 {
+#ifdef HOST_NONSHM_PLUGIN
+  struct nonshm_thread *thd
+    = GOMP_PLUGIN_malloc (sizeof (struct nonshm_thread));
+  thd->nonshm_exec = false;
+  return thd;
+#else
   return NULL;
+#endif
 }
 
 STATIC void
-GOMP_OFFLOAD_openacc_destroy_thread_data (void *tls_data
-					  __attribute__ ((unused)))
+GOMP_OFFLOAD_openacc_destroy_thread_data (void *tls_data)
 {
+#ifdef HOST_NONSHM_PLUGIN
+  free (tls_data);
+#endif
 }
diff --git a/libgomp/plugin/plugin-host.h b/libgomp/plugin/plugin-host.h
new file mode 100644
index 0000000..96955d1
--- /dev/null
+++ b/libgomp/plugin/plugin-host.h
@@ -0,0 +1,37 @@
+/* OpenACC Runtime Library: acc_device_host, acc_device_host_nonshm.
+
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   Contributed by Mentor Embedded.
+
+   This file is part of the GNU Offloading and Multi Processing Library
+   (libgomp).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+   more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef PLUGIN_HOST_H
+#define PLUGIN_HOST_H
+
+struct nonshm_thread
+{
+  bool nonshm_exec;
+};
+
+#endif
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c
index 81ea476..25cc15a 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_on_device-1.c
@@ -1,7 +1,3 @@
-/* Disable the acc_on_device builtin; we want to test the libgomp library
-   function.  */
-/* { dg-additional-options "-fno-builtin-acc_on_device" } */
-
 #include <stdlib.h>
 #include <openacc.h>
 
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c
index 184b355..6aa3bb7 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/if-1.c
@@ -1,5 +1,4 @@
 /* { dg-do run } */
-/* { dg-additional-options "-fno-builtin-acc_on_device" } */
 
 #include <openacc.h>
 #include <stdlib.h>
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90
index 4488818..729b685 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90
@@ -1,8 +1,4 @@
 ! { dg-additional-options "-cpp" }
-! TODO: Have to disable the acc_on_device builtin for we want to test the
-! libgomp library function?  The command line option
-! '-fno-builtin-acc_on_device' is valid for C/C++/ObjC/ObjC++ but not for
-! Fortran.
 
 use openacc
 implicit none
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
index 0047a19..19ff4a5 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
@@ -1,8 +1,4 @@
 ! { dg-additional-options "-cpp" }
-! TODO: Have to disable the acc_on_device builtin for we want to test
-! the libgomp library function?  The command line option
-! '-fno-builtin-acc_on_device' is valid for C/C++/ObjC/ObjC++ but not
-! for Fortran.
 
       USE OPENACC
       IMPLICIT NONE
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f
index 49d7a72..b01c553 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f
@@ -1,8 +1,4 @@
 ! { dg-additional-options "-cpp" }
-! TODO: Have to disable the acc_on_device builtin for we want to test
-! the libgomp library function?  The command line option
-! '-fno-builtin-acc_on_device' is valid for C/C++/ObjC/ObjC++ but not
-! for Fortran.
 
       IMPLICIT NONE
       INCLUDE "openacc_lib.h"
 
--- a/gcc/c/c-parser.c	2015-04-20 18:55:33.000000000 +0200
+++ b/gcc/c/c-parser.c	2015-05-23 11:32:41.664037866 +0200
@@ -13069,12 +13069,9 @@
 		      }
 		    else
 		      {
-			/* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES,
-			   change it to shared (decl) in
-			   OMP_PARALLEL_CLAUSES.  */
-			tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c),
-						   OMP_CLAUSE_LASTPRIVATE);
-			OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c);
+			/* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
+			tree l = *c;
+			*c = OMP_CLAUSE_CHAIN (*c);
 			if (code == OMP_SIMD)
 			  {
 			    OMP_CLAUSE_CHAIN (l)
@@ -13086,7 +13083,6 @@
 			    OMP_CLAUSE_CHAIN (l) = clauses;
 			    clauses = l;
 			  }
-			OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
 		      }
 		  }
 	    }
@@ -13771,6 +13767,7 @@
 	  TREE_TYPE (ret) = void_type_node;
 	  OMP_TEAMS_CLAUSES (ret) = clauses;
 	  OMP_TEAMS_BODY (ret) = block;
+	  OMP_TEAMS_COMBINED (ret) = 1;
 	  return add_stmt (ret);
 	}
     }
--- a/gcc/calls.c	2015-04-07 23:02:12.000000000 +0200
+++ b/gcc/calls.c	2015-05-23 11:18:33.952634193 +0200
@@ -2099,6 +2099,26 @@
 					   (XEXP (args[i].value, 0), size)))
 		*sibcall_failure = 1;
 
+	      if (size % UNITS_PER_WORD == 0
+		  || MEM_ALIGN (mem) % BITS_PER_WORD == 0)
+		move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
+	      else
+		{
+		  if (nregs > 1)
+		    move_block_to_reg (REGNO (reg), mem, nregs - 1,
+				       args[i].mode);
+		  rtx dest = gen_rtx_REG (word_mode, REGNO (reg) + nregs - 1);
+		  unsigned int bitoff = (nregs - 1) * BITS_PER_WORD;
+		  unsigned int bitsize = size * BITS_PER_UNIT - bitoff;
+		  rtx x = extract_bit_field (mem, bitsize, bitoff, 1,
+					     dest, word_mode, word_mode);
+		  if (BYTES_BIG_ENDIAN)
+		    x = expand_shift (LSHIFT_EXPR, word_mode, x,
+				      BITS_PER_WORD - bitsize, dest, 1);
+		  if (x != dest)
+		    emit_move_insn (dest, x);
+		}
+
 	      /* Handle a BLKmode that needs shifting.  */
 	      if (nregs == 1 && size < UNITS_PER_WORD
 #ifdef BLOCK_REG_PADDING
@@ -2106,22 +2126,18 @@
 #else
 		  && BYTES_BIG_ENDIAN
 #endif
-		 )
+		  )
 		{
-		  rtx tem = operand_subword_force (mem, 0, args[i].mode);
-		  rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
-		  rtx x = gen_reg_rtx (word_mode);
+		  rtx dest = gen_rtx_REG (word_mode, REGNO (reg));
 		  int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
-		  enum tree_code dir = BYTES_BIG_ENDIAN ? RSHIFT_EXPR
-							: LSHIFT_EXPR;
+		  enum tree_code dir = (BYTES_BIG_ENDIAN
+					? RSHIFT_EXPR : LSHIFT_EXPR);
+		  rtx x;
 
-		  emit_move_insn (x, tem);
-		  x = expand_shift (dir, word_mode, x, shift, ri, 1);
-		  if (x != ri)
-		    emit_move_insn (ri, x);
+		  x = expand_shift (dir, word_mode, dest, shift, dest, 1);
+		  if (x != dest)
+		    emit_move_insn (dest, x);
 		}
-	      else
-		move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
 	    }
 
 	  /* When a parameter is a block, and perhaps in other cases, it is
--- a/gcc/config/i386/i386.c	2015-04-17 23:55:05.000000000 +0200
+++ b/gcc/config/i386/i386.c	2015-05-23 11:27:55.981186322 +0200
@@ -2988,6 +2988,17 @@
           return;
         }
 
+      if ((stringop_alg) i == rep_prefix_8_byte
+	  && !TARGET_64BIT)
+	{
+	  /* rep; movq isn't available in 32-bit code.  */
+	  error ("stringop strategy name %s specified for option %s "
+		 "not supported for 32-bit code",
+                 alg_name,
+                 is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+	  return;
+	}
+
       input_ranges[n].max = maxs;
       input_ranges[n].alg = (stringop_alg) i;
       if (!strcmp (align, "align"))
@@ -5867,7 +5878,10 @@
 /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
    DFmode (2) arguments in SSE registers for a function with the
    indicated TYPE and DECL.  DECL may be NULL when calling function
-   indirectly or considering a libcall.  Otherwise return 0.  */
+   indirectly or considering a libcall.  Return -1 if any FP parameter
+   should be rejected by error.  This is used in siutation we imply SSE
+   calling convetion but the function is called from another function with
+   SSE disabled. Otherwise return 0.  */
 
 static int
 ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
@@ -5916,14 +5930,13 @@
 	{
 	  /* Refuse to produce wrong code when local function with SSE enabled
 	     is called from SSE disabled function.
-	     We may work hard to work out these scenarios but hopefully
-	     it doesnot matter in practice.  */
+	     FIXME: We need a way to detect these cases cross-ltrans partition
+	     and avoid using SSE calling conventions on local functions called
+	     from function with SSE disabled.  For now at least delay the
+	     warning until we know we are going to produce wrong code.
+	     See PR66047  */
 	  if (!TARGET_SSE && warn)
-	    {
-	      error ("calling %qD with SSE caling convention without "
-		     "SSE/SSE2 enabled", decl);
-	      return 0;
-	    }
+	    return -1;
 	  return TARGET_SSE2_P (target_opts_for_fn (target->decl)
 				->x_ix86_isa_flags) ? 2 : 1;
 	}
@@ -6479,6 +6492,7 @@
   cum->bnd_regno = FIRST_BND_REG;
   cum->bnds_in_bt = 0;
   cum->force_bnd_pass = 0;
+  cum->decl = fndecl;
 
   if (!TARGET_64BIT)
     {
@@ -7424,6 +7438,7 @@
 			 HOST_WIDE_INT words)
 {
   int res = 0;
+  bool error_p = NULL;
 
   switch (mode)
     {
@@ -7456,9 +7471,13 @@
       gcc_unreachable ();
 
     case DFmode:
+      if (cum->float_in_sse == -1)
+	error_p = 1;
       if (cum->float_in_sse < 2)
 	break;
     case SFmode:
+      if (cum->float_in_sse == -1)
+	error_p = 1;
       if (cum->float_in_sse < 1)
 	break;
       /* FALLTHRU */
@@ -7514,6 +7533,14 @@
 	}
       break;
     }
+  if (error_p)
+    {
+      cum->float_in_sse = 0;
+      error ("calling %qD with SSE calling convention without "
+	     "SSE/SSE2 enabled", cum->decl);
+      sorry ("this is a GCC bug that can be worked around by adding "
+	     "attribute used to function called");
+    }
 
   return res;
 }
@@ -7646,10 +7673,11 @@
     (otherwise it is an extra parameter matching an ellipsis).  */
 
 static rtx
-function_arg_32 (const CUMULATIVE_ARGS *cum, machine_mode mode,
+function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
 		 machine_mode orig_mode, const_tree type,
 		 HOST_WIDE_INT bytes, HOST_WIDE_INT words)
 {
+  bool error_p = false;
   /* Avoid the AL settings for the Unix64 ABI.  */
   if (mode == VOIDmode)
     return constm1_rtx;
@@ -7690,9 +7718,13 @@
       break;
 
     case DFmode:
+      if (cum->float_in_sse == -1)
+	error_p = 1;
       if (cum->float_in_sse < 2)
 	break;
     case SFmode:
+      if (cum->float_in_sse == -1)
+	error_p = 1;
       if (cum->float_in_sse < 1)
 	break;
       /* FALLTHRU */
@@ -7751,6 +7783,14 @@
 	}
       break;
     }
+  if (error_p)
+    {
+      cum->float_in_sse = 0;
+      error ("calling %qD with SSE calling convention without "
+	     "SSE/SSE2 enabled", cum->decl);
+      sorry ("this is a GCC bug that can be worked around by adding "
+	     "attribute used to function called");
+    }
 
   return NULL_RTX;
 }
@@ -8230,8 +8270,15 @@
   if ((fn || fntype) && (mode == SFmode || mode == DFmode))
     {
       int sse_level = ix86_function_sseregparm (fntype, fn, false);
-      if ((sse_level >= 1 && mode == SFmode)
-	  || (sse_level == 2 && mode == DFmode))
+      if (sse_level == -1)
+	{
+	  error ("calling %qD with SSE caling convention without "
+		 "SSE/SSE2 enabled", fn);
+	  sorry ("this is a GCC bug that can be worked around by adding "
+		 "attribute used to function called");
+	}
+      else if ((sse_level >= 1 && mode == SFmode)
+	       || (sse_level == 2 && mode == DFmode))
 	regno = FIRST_SSE_REG;
     }
 
@@ -46892,15 +46939,16 @@
 static bool
 expand_vec_perm_blend (struct expand_vec_perm_d *d)
 {
-  machine_mode vmode = d->vmode;
+  machine_mode mmode, vmode = d->vmode;
   unsigned i, mask, nelt = d->nelt;
-  rtx target, op0, op1, x;
+  rtx target, op0, op1, maskop, x;
   rtx rperm[32], vperm;
 
   if (d->one_operand_p)
     return false;
   if (TARGET_AVX512F && GET_MODE_SIZE (vmode) == 64
-      && GET_MODE_SIZE (GET_MODE_INNER (vmode)) >= 4)
+      && (TARGET_AVX512BW
+	  || GET_MODE_SIZE (GET_MODE_INNER (vmode)) >= 4))
     ;
   else if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32)
     ;
@@ -47074,8 +47122,33 @@
       gcc_unreachable ();
     }
 
+  switch (vmode)
+    {
+    case V8DFmode:
+    case V8DImode:
+      mmode = QImode;
+      break;
+    case V16SFmode:
+    case V16SImode:
+      mmode = HImode;
+      break;
+    case V32HImode:
+      mmode = SImode;
+      break;
+    case V64QImode:
+      mmode = DImode;
+      break;
+    default:
+      mmode = VOIDmode;
+    }
+  
+  if (mmode != VOIDmode)
+    maskop = force_reg (mmode, gen_int_mode (mask, mmode));
+  else
+    maskop = GEN_INT (mask);
+
   /* This matches five different patterns with the different modes.  */
-  x = gen_rtx_VEC_MERGE (vmode, op1, op0, GEN_INT (mask));
+  x = gen_rtx_VEC_MERGE (vmode, op1, op0, maskop);
   x = gen_rtx_SET (VOIDmode, target, x);
   emit_insn (x);
   if (target != d->target)
@@ -51606,7 +51679,7 @@
   for (i = 0; i < loop->num_nodes; i++)
     FOR_BB_INSNS (bbs[i], insn)
       if (NONDEBUG_INSN_P (insn))
-	FOR_EACH_SUBRTX (iter, array, insn, NONCONST)
+	FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
 	  if (const_rtx x = *iter)
 	    if (MEM_P (x))
 	      {
--- a/gcc/config/i386/i386.h	2015-02-21 01:06:53.000000000 +0100
+++ b/gcc/config/i386/i386.h	2015-05-23 11:26:56.002281385 +0200
@@ -1682,6 +1682,7 @@
   int stdarg;                   /* Set to 1 if function is stdarg.  */
   enum calling_abi call_abi;	/* Set to SYSV_ABI for sysv abi. Otherwise
  				   MS_ABI for ms abi.  */
+  tree decl;			/* Callee decl.  */
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
--- a/gcc/config/i386/sse.md	2015-04-09 23:37:28.000000000 +0200
+++ b/gcc/config/i386/sse.md	2015-05-23 11:18:33.954634308 +0200
@@ -9523,7 +9523,7 @@
 	(mult:V4DI
 	  (sign_extend:V4DI
 	    (vec_select:V4SI
-	      (match_operand:V8SI 1 "nonimmediate_operand" "v")
+	      (match_operand:V8SI 1 "nonimmediate_operand" "%v")
 	      (parallel [(const_int 0) (const_int 2)
 			 (const_int 4) (const_int 6)])))
 	  (sign_extend:V4DI
--- a/gcc/cp/constexpr.c	2015-04-12 21:10:58.000000000 +0200
+++ b/gcc/cp/constexpr.c	2015-05-23 11:18:33.955634365 +0200
@@ -1355,7 +1355,14 @@
 		     fun = DECL_CHAIN (fun))
 		  if (DECL_SAVED_TREE (fun))
 		    break;
-	      gcc_assert (DECL_SAVED_TREE (fun));
+	      if (!DECL_SAVED_TREE (fun))
+		{
+		  /* cgraph/gimplification have released the DECL_SAVED_TREE
+		     for this function.  Fail gracefully.  */
+		  gcc_assert (ctx->quiet);
+		  *non_constant_p = true;
+		  return t;
+		}
 	      tree parms, res;
 
 	      /* Unshare the whole function body.  */
@@ -2603,14 +2610,29 @@
 {
   constexpr_ctx new_ctx = *ctx;
 
+  tree init = TREE_OPERAND (t, 1);
+
   /* First we figure out where we're storing to.  */
   tree target = TREE_OPERAND (t, 0);
+  tree type = TREE_TYPE (target);
   target = cxx_eval_constant_expression (ctx, target,
 					 true,
 					 non_constant_p, overflow_p);
   if (*non_constant_p)
     return t;
 
+  if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (target), type)
+      && is_empty_class (type))
+    {
+      /* For initialization of an empty base, the original target will be
+         *(base*)this, which the above evaluation resolves to the object
+	 argument, which has the derived type rather than the base type.  In
+	 this situation, just evaluate the initializer and return, since
+	 there's no actual data to store.  */
+      return cxx_eval_constant_expression (ctx, init, false,
+					   non_constant_p, overflow_p);
+    }
+
   /* And then find the underlying variable.  */
   vec<tree,va_gc> *refs = make_tree_vector();
   tree object = NULL_TREE;
@@ -2647,7 +2669,7 @@
       *non_constant_p = true;
       return t;
     }
-  tree type = TREE_TYPE (object);
+  type = TREE_TYPE (object);
   while (!refs->is_empty())
     {
       if (*valp == NULL_TREE)
@@ -2684,9 +2706,8 @@
       new_ctx.object = target;
     }
 
-  tree init = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 1),
-					    false,
-					    non_constant_p, overflow_p);
+  init = cxx_eval_constant_expression (&new_ctx, init, false,
+				       non_constant_p, overflow_p);
   if (target == object)
     /* The hash table might have moved since the get earlier.  */
     ctx->values->put (object, init);
--- a/gcc/cp/cvt.c	2015-01-09 21:18:42.000000000 +0100
+++ b/gcc/cp/cvt.c	2015-05-23 11:18:33.956634423 +0200
@@ -603,8 +603,20 @@
 tree
 cp_fold_convert (tree type, tree expr)
 {
-  tree conv = fold_convert (type, expr);
-  conv = ignore_overflows (conv, expr);
+  tree conv;
+  if (TREE_TYPE (expr) == type)
+    conv = expr;
+  else if (TREE_CODE (expr) == PTRMEM_CST)
+    {
+      /* Avoid wrapping a PTRMEM_CST in NOP_EXPR.  */
+      conv = copy_node (expr);
+      TREE_TYPE (conv) = type;
+    }
+  else
+    {
+      conv = fold_convert (type, expr);
+      conv = ignore_overflows (conv, expr);
+    }
   return conv;
 }
 
--- a/gcc/cp/decl2.c	2015-03-19 20:12:43.000000000 +0100
+++ b/gcc/cp/decl2.c	2015-05-23 11:24:52.397411028 +0200
@@ -1175,6 +1175,10 @@
       && is_attribute_p ("omp declare simd", name))
     return true;
 
+  /* An attribute pack is clearly dependent.  */
+  if (args && PACK_EXPANSION_P (args))
+    return true;
+
   /* If any of the arguments are dependent expressions, we can't evaluate
      the attribute until instantiation time.  */
   for (arg = args; arg; arg = TREE_CHAIN (arg))
--- a/gcc/cp/decl.c	2015-04-02 18:43:02.000000000 +0200
+++ b/gcc/cp/decl.c	2015-05-23 11:23:34.737303073 +0200
@@ -4825,8 +4825,11 @@
 
   was_public = TREE_PUBLIC (decl);
 
-  /* Enter this declaration into the symbol table.  */
-  decl = maybe_push_decl (decl);
+  /* Enter this declaration into the symbol table.  Don't push the plain
+     VAR_DECL for a variable template.  */
+  if (!template_parm_scope_p ()
+      || TREE_CODE (decl) != VAR_DECL)
+    decl = maybe_push_decl (decl);
 
   if (processing_template_decl)
     decl = push_template_decl (decl);
@@ -10628,7 +10631,7 @@
       }
     else if (decl_context == FIELD)
       {
-	if (!staticp && TREE_CODE (type) != METHOD_TYPE
+	if (!staticp && !friendp && TREE_CODE (type) != METHOD_TYPE
 	    && type_uses_auto (type))
 	  {
 	    error ("non-static data member declared %<auto%>");
--- a/gcc/cp/lambda.c	2015-04-03 19:23:27.000000000 +0200
+++ b/gcc/cp/lambda.c	2015-05-23 11:18:33.958634538 +0200
@@ -787,7 +787,7 @@
       /* In a lambda, need to go through 'this' capture.  */
       tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
       tree cap = lambda_expr_this_capture (lam, add_capture_p);
-      if (cap != error_mark_node)
+      if (cap && cap != error_mark_node)
 	object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
 				       RO_NULL, tf_warning_or_error);
     }
--- a/gcc/cp/name-lookup.c	2015-04-01 23:27:55.000000000 +0200
+++ b/gcc/cp/name-lookup.c	2015-05-23 11:18:33.958634538 +0200
@@ -3408,7 +3408,7 @@
 			   tf_warning_or_error);
       if (b_kind < bk_proper_base)
 	{
-	  if (!bases_dependent_p)
+	  if (!bases_dependent_p || b_kind == bk_same_type)
 	    {
 	      error_not_base_type (scope, current_class_type);
 	      return NULL_TREE;
--- a/gcc/cp/parser.c	2015-04-20 18:55:33.000000000 +0200
+++ b/gcc/cp/parser.c	2015-05-23 11:32:41.668037917 +0200
@@ -22500,6 +22500,13 @@
 	  attributes = attribute;
 	}
       token = cp_lexer_peek_token (parser->lexer);
+      if (token->type == CPP_ELLIPSIS)
+	{
+	  cp_lexer_consume_token (parser->lexer);
+	  TREE_VALUE (attribute)
+	    = make_pack_expansion (TREE_VALUE (attribute));
+	  token = cp_lexer_peek_token (parser->lexer);
+	}
       if (token->type != CPP_COMMA)
 	break;
       cp_lexer_consume_token (parser->lexer);
@@ -22578,20 +22585,27 @@
 	    return alignas_expr;
 	}
 
+      alignas_expr = cxx_alignas_expr (alignas_expr);
+      alignas_expr = build_tree_list (NULL_TREE, alignas_expr);
+
+      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+	{
+	  cp_lexer_consume_token (parser->lexer);
+	  alignas_expr = make_pack_expansion (alignas_expr);
+	}
+
       if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) == NULL)
 	{
 	  cp_parser_error (parser, "expected %<)%>");
 	  return error_mark_node;
 	}
 
-      alignas_expr = cxx_alignas_expr (alignas_expr);
-
       /* Build the C++-11 representation of an 'aligned'
 	 attribute.  */
       attributes =
 	build_tree_list (build_tree_list (get_identifier ("gnu"),
 					  get_identifier ("aligned")),
-			 build_tree_list (NULL_TREE, alignas_expr));
+			 alignas_expr);
     }
 
   return attributes;
@@ -30466,11 +30480,9 @@
 	    else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_LASTPRIVATE
 		     && OMP_CLAUSE_DECL (*c) == real_decl)
 	      {
-		/* Add lastprivate (decl) clause to OMP_FOR_CLAUSES,
-		   change it to shared (decl) in OMP_PARALLEL_CLAUSES.  */
-		tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
-		OMP_CLAUSE_DECL (l) = real_decl;
-		CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c);
+		/* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
+		tree l = *c;
+		*c = OMP_CLAUSE_CHAIN (*c);
 		if (code == OMP_SIMD)
 		  {
 		    OMP_CLAUSE_CHAIN (l) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
@@ -30481,8 +30493,6 @@
 		    OMP_CLAUSE_CHAIN (l) = clauses;
 		    clauses = l;
 		  }
-		OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
-		CP_OMP_CLAUSE_INFO (*c) = NULL;
 		add_private_clause = false;
 	      }
 	    else
@@ -31316,6 +31326,7 @@
 	  TREE_TYPE (ret) = void_type_node;
 	  OMP_TEAMS_CLAUSES (ret) = clauses;
 	  OMP_TEAMS_BODY (ret) = body;
+	  OMP_TEAMS_COMBINED (ret) = 1;
 	  return add_stmt (ret);
 	}
     }
--- a/gcc/cp/pt.c	2015-04-01 23:27:55.000000000 +0200
+++ b/gcc/cp/pt.c	2015-05-23 11:27:30.146802454 +0200
@@ -1919,7 +1919,13 @@
     ++header_count;
 
   if (variable_template_p (fns))
-    templates = tree_cons (explicit_targs, fns, templates);
+    {
+      tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (fns));
+      targs = coerce_template_parms (parms, explicit_targs, fns,
+				     tf_warning_or_error,
+				     /*req_all*/true, /*use_defarg*/true);
+      templates = tree_cons (targs, fns, templates);
+    }
   else for (; fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
@@ -3338,9 +3344,9 @@
   if (!arg || arg == error_mark_node)
     return arg;
 
-  if (TREE_CODE (arg) == TREE_LIST)
+  if (TREE_CODE (arg) == TREE_LIST && TREE_PURPOSE (arg))
     {
-      /* The only time we will see a TREE_LIST here is for a base
+      /* A TREE_LIST with a non-null TREE_PURPOSE is for a base
          class initializer.  In this case, the TREE_PURPOSE will be a
          _TYPE node (representing the base class expansion we're
          initializing) and the TREE_VALUE will be a TREE_LIST
@@ -9065,6 +9071,21 @@
 		      = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)),
 				   chain);
 		}
+	      else if (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t)))
+		{
+		  /* An attribute pack expansion.  */
+		  tree purp = TREE_PURPOSE (t);
+		  tree pack = (tsubst_pack_expansion
+			       (TREE_VALUE (t), args, complain, in_decl));
+		  int len = TREE_VEC_LENGTH (pack);
+		  for (int i = 0; i < len; ++i)
+		    {
+		      tree elt = TREE_VEC_ELT (pack, i);
+		      *q = build_tree_list (purp, elt);
+		      q = &TREE_CHAIN (*q);
+		    }
+		  continue;
+		}
 	      else
 		TREE_VALUE (t)
 		  = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
@@ -11302,6 +11323,11 @@
 		tmpl = DECL_TI_TEMPLATE (t);
 		gen_tmpl = most_general_template (tmpl);
 		argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
+		if (argvec != error_mark_node)
+		  argvec = (coerce_innermost_template_parms
+			    (DECL_TEMPLATE_PARMS (gen_tmpl),
+			     argvec, t, complain,
+			     /*all*/true, /*defarg*/true));
 		if (argvec == error_mark_node)
 		  RETURN (error_mark_node);
 		hash = hash_tmpl_and_args (gen_tmpl, argvec);
@@ -14249,7 +14275,7 @@
       tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false,
 				args, complain, in_decl);
       t = copy_node (t);
-      OMP_CLAUSES (t) = tmp;
+      OMP_TARGET_UPDATE_CLAUSES (t) = tmp;
       add_stmt (t);
       break;
 
--- a/gcc/cp/tree.c	2015-04-09 22:11:44.000000000 +0200
+++ b/gcc/cp/tree.c	2015-05-23 11:27:15.316578155 +0200
@@ -1207,6 +1207,7 @@
     {
       bool changed = false;
       vec<tree,va_gc> *vec = make_tree_vector ();
+      tree r = t;
       for (; t; t = TREE_CHAIN (t))
 	{
 	  gcc_assert (!TREE_PURPOSE (t));
@@ -1215,7 +1216,6 @@
 	    changed = true;
 	  vec_safe_push (vec, elt);
 	}
-      tree r = t;
       if (changed)
 	r = build_tree_list_vec (vec);
       release_tree_vector (vec);
@@ -1350,7 +1350,7 @@
     case DECLTYPE_TYPE:
       result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t));
       if (result == DECLTYPE_TYPE_EXPR (t))
-	return t;
+	result = NULL_TREE;
       else
 	result = (finish_decltype_type
 		  (result,
@@ -1424,8 +1424,8 @@
 	    && type2 == TRAIT_EXPR_TYPE2 (t))
 	  return t;
 	r = copy_node (t);
-	TRAIT_EXPR_TYPE1 (t) = type1;
-	TRAIT_EXPR_TYPE2 (t) = type2;
+	TRAIT_EXPR_TYPE1 (r) = type1;
+	TRAIT_EXPR_TYPE2 (r) = type2;
 	return r;
       }
 
--- a/gcc/cp/typeck2.c	2015-01-23 17:30:00.000000000 +0100
+++ b/gcc/cp/typeck2.c	2015-05-23 11:24:32.144136275 +0200
@@ -957,9 +957,16 @@
 	    }
 	}
       else if (complain & tf_error)
-	error_at (EXPR_LOC_OR_LOC (init, input_location),
-		  "narrowing conversion of %qE from %qT to %qT inside { }",
-		  init, ftype, type);
+	{
+	  int savederrorcount = errorcount;
+	  global_dc->pedantic_errors = 1;
+	  pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
+		   "narrowing conversion of %qE from %qT to %qT "
+		   "inside { }", init, ftype, type);
+	  if (errorcount == savederrorcount)
+	    ok = true;
+	  global_dc->pedantic_errors = flag_pedantic_errors;
+	}
     }
 
   return cxx_dialect == cxx98 || ok; 
@@ -1089,6 +1096,19 @@
 	      || TREE_CODE (type) == UNION_TYPE
 	      || TREE_CODE (type) == COMPLEX_TYPE);
 
+  /* "If T is a class type and the initializer list has a single
+     element of type cv U, where U is T or a class derived from T,
+     the object is initialized from that element."  */
+  if (cxx_dialect >= cxx11
+      && BRACE_ENCLOSED_INITIALIZER_P (init)
+      && CONSTRUCTOR_NELTS (init) == 1
+      && (CLASS_TYPE_P (type) || VECTOR_TYPE_P (type)))
+    {
+      tree elt = CONSTRUCTOR_ELT (init, 0)->value;
+      if (reference_related_p (type, TREE_TYPE (elt)))
+	init = elt;
+    }
+
   if (BRACE_ENCLOSED_INITIALIZER_P (init)
       && !TYPE_NON_AGGREGATE_CLASS (type))
     return process_init_constructor (type, init, complain);
--- a/gcc/fortran/check.c	2015-03-02 19:56:51.000000000 +0100
+++ b/gcc/fortran/check.c	2015-05-23 11:29:30.690530828 +0200
@@ -6213,6 +6213,15 @@
 bool
 gfc_check_storage_size (gfc_expr *a, gfc_expr *kind)
 {
+
+  if (a->expr_type == EXPR_NULL)
+    {
+      gfc_error ("Intrinsic function NULL at %L cannot be an actual "
+		 "argument to STORAGE_SIZE, because it returns a "
+		 "disassociated pointer", &a->where);
+      return false;
+    }
+
   if (a->ts.type == BT_ASSUMED)
     {
       gfc_error ("%qs argument of %qs intrinsic at %L shall not be TYPE(*)",
--- a/gcc/fortran/decl.c	2015-04-10 13:29:53.000000000 +0200
+++ b/gcc/fortran/decl.c	2015-05-23 11:30:42.240495466 +0200
@@ -1404,9 +1404,7 @@
 		    }
 		  else if (init->expr_type == EXPR_ARRAY)
 		    {
-		      gfc_constructor *c;
-		      c = gfc_constructor_first (init->value.constructor);
-		      clen = c->expr->value.character.length;
+		      clen = mpz_get_si (init->ts.u.cl->length->value.integer);
 		      sym->ts.u.cl->length
 				= gfc_get_int_expr (gfc_default_integer_kind,
 						    NULL, clen);
@@ -5594,7 +5592,7 @@
 		       "a contained subprogram");
 	    break;
 	  default:
-	    gfc_internal_error ("gfc_match_entry(): Bad state");
+	    gfc_error ("Unexpected ENTRY statement at %C");
 	}
       return MATCH_ERROR;
     }
@@ -6970,7 +6968,8 @@
   gfc_symbol *sym;
   match m;
 
-  if (gfc_current_ns->proc_name->attr.flavor != FL_MODULE)
+  if (!gfc_current_ns->proc_name
+      || gfc_current_ns->proc_name->attr.flavor != FL_MODULE)
     {
        gfc_error ("PROTECTED at %C only allowed in specification "
 		  "part of a module");
@@ -8512,6 +8511,11 @@
 		gfc_op2string (op));
       break;
 
+    case INTERFACE_NAMELESS:
+      gfc_error ("Malformed GENERIC statement at %C");
+      goto error;
+      break;
+
     default:
       gcc_unreachable ();
     }
--- a/gcc/fortran/expr.c	2015-02-06 19:15:01.000000000 +0100
+++ b/gcc/fortran/expr.c	2015-05-23 11:30:07.135026771 +0200
@@ -3118,19 +3118,22 @@
 	bad_proc = true;
 
       /* (ii) The assignment is in the main program; or  */
-      if (gfc_current_ns->proc_name->attr.is_main_program)
+      if (gfc_current_ns->proc_name
+	  && gfc_current_ns->proc_name->attr.is_main_program)
 	bad_proc = true;
 
       /* (iii) A module or internal procedure...  */
-      if ((gfc_current_ns->proc_name->attr.proc == PROC_INTERNAL
-	   || gfc_current_ns->proc_name->attr.proc == PROC_MODULE)
+      if (gfc_current_ns->proc_name
+	  && (gfc_current_ns->proc_name->attr.proc == PROC_INTERNAL
+	      || gfc_current_ns->proc_name->attr.proc == PROC_MODULE)
 	  && gfc_current_ns->parent
 	  && (!(gfc_current_ns->parent->proc_name->attr.function
 		|| gfc_current_ns->parent->proc_name->attr.subroutine)
 	      || gfc_current_ns->parent->proc_name->attr.is_main_program))
 	{
 	  /* ... that is not a function...  */
-	  if (!gfc_current_ns->proc_name->attr.function)
+	  if (gfc_current_ns->proc_name
+	      && !gfc_current_ns->proc_name->attr.function)
 	    bad_proc = true;
 
 	  /* ... or is not an entry and has a different name.  */
--- a/gcc/fortran/interface.c	2015-02-01 01:29:54.000000000 +0100
+++ b/gcc/fortran/interface.c	2015-05-23 11:30:58.232706361 +0200
@@ -346,8 +346,12 @@
 		break;
 
 	      m = MATCH_ERROR;
-	      gfc_error ("Expecting %<END INTERFACE OPERATOR (%s)%> at %C, "
-			 "but got %s", s1, s2);
+	      if (strcmp(s2, "none") == 0)
+		gfc_error ("Expecting %<END INTERFACE OPERATOR (%s)%> "
+			   "at %C, ", s1);
+	      else		
+		gfc_error ("Expecting %<END INTERFACE OPERATOR (%s)%> at %C, "
+			   "but got %s", s1, s2);
 	    }
 
 	}
--- a/gcc/fortran/io.c	2015-02-01 01:29:54.000000000 +0100
+++ b/gcc/fortran/io.c	2015-05-23 11:31:18.785975216 +0200
@@ -385,7 +385,7 @@
 
 	  if (c == delim)
 	    {
-	      c = next_char (INSTRING_NOWARN);
+	      c = next_char (NONSTRING);
 
 	      if (c == '\0')
 		{
@@ -2382,9 +2382,7 @@
   if (m == MATCH_NO)
     {
       m = gfc_match_expr (&fp->unit);
-      if (m == MATCH_ERROR)
-	goto done;
-      if (m == MATCH_NO)
+      if (m == MATCH_ERROR || m == MATCH_NO)
 	goto syntax;
     }
 
--- a/gcc/fortran/match.c	2015-01-15 21:11:12.000000000 +0100
+++ b/gcc/fortran/match.c	2015-05-23 11:30:58.232706361 +0200
@@ -110,6 +110,9 @@
     case INTRINSIC_PARENTHESES:
       return "parens";
 
+    case INTRINSIC_NONE:
+      return "none";
+
     default:
       break;
     }
--- a/gcc/fortran/parse.c	2015-02-01 01:29:54.000000000 +0100
+++ b/gcc/fortran/parse.c	2015-05-23 11:29:15.011314175 +0200
@@ -2425,8 +2425,7 @@
       break;
 
     default:
-      gfc_internal_error ("Unexpected %s statement in verify_st_order() at %C",
-			  gfc_ascii_statement (st));
+      return false;
     }
 
   /* All is well, record the statement in case we need it next time.  */
--- a/gcc/fortran/scanner.c	2015-02-13 17:57:28.000000000 +0100
+++ b/gcc/fortran/scanner.c	2015-05-23 11:31:18.785975216 +0200
@@ -1272,21 +1272,11 @@
 	 are still in a string and we are looking for a possible
 	 doubled quote and we end up here. See PR64506.  */
 
-      if (in_string)
+      if (in_string && c != '\n')
 	{
 	  gfc_current_locus = old_loc;
-
-	  if (c == '!')
-	    {
-	      skip_comment_line ();
-	      goto restart;
-	    }
-
-	  if (c != '\n')
-	    {
-	      c = '&';
-	      goto done;
-	    }
+	  c = '&';
+	  goto done;
 	}
 
       if (c != '!' && c != '\n')
@@ -1392,6 +1382,8 @@
 			     "Missing %<&%> in continued character "
 			     "constant at %C");
 	    }
+	  else if (!in_string && (c == '\'' || c == '"'))
+	      goto done;
 	  /* Both !$omp and !$ -fopenmp continuation lines have & on the
 	     continuation line only optionally.  */
 	  else if (openmp_flag || openacc_flag || openmp_cond_flag)
--- a/gcc/fortran/symbol.c	2015-04-10 13:29:53.000000000 +0200
+++ b/gcc/fortran/symbol.c	2015-05-23 11:28:41.895849323 +0200
@@ -458,6 +458,11 @@
 	}
     }
 
+  if (attr->dummy && ((attr->function || attr->subroutine) && 
+			gfc_current_state () == COMP_CONTAINS))
+    gfc_error_now ("internal procedure '%s' at %L conflicts with "
+		   "DUMMY argument", name, where);
+
   conf (dummy, entry);
   conf (dummy, intrinsic);
   conf (dummy, threadprivate);
--- a/gcc/fortran/trans-openmp.c	2015-03-30 19:54:05.000000000 +0200
+++ b/gcc/fortran/trans-openmp.c	2015-05-23 11:32:41.669037929 +0200
@@ -4114,6 +4114,7 @@
   stmtblock_t block;
   gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
   tree stmt, omp_clauses = NULL_TREE;
+  bool combined = true;
 
   gfc_start_block (&block);
   if (clausesa == NULL)
@@ -4130,6 +4131,7 @@
     case EXEC_OMP_TARGET_TEAMS:
     case EXEC_OMP_TEAMS:
       stmt = gfc_trans_omp_code (code->block->next, true);
+      combined = false;
       break;
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TEAMS_DISTRIBUTE:
@@ -4143,6 +4145,8 @@
     }
   stmt = build2_loc (input_location, OMP_TEAMS, void_type_node, stmt,
 		     omp_clauses);
+  if (combined)
+    OMP_TEAMS_COMBINED (stmt) = 1;
   gfc_add_expr_to_block (&block, stmt);
   return gfc_finish_block (&block);
 }
@@ -4163,9 +4167,14 @@
   if (code->op == EXEC_OMP_TARGET)
     stmt = gfc_trans_omp_code (code->block->next, true);
   else
-    stmt = gfc_trans_omp_teams (code, clausesa);
-  if (TREE_CODE (stmt) != BIND_EXPR)
-    stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
+    {
+      pushlevel ();
+      stmt = gfc_trans_omp_teams (code, clausesa);
+      if (TREE_CODE (stmt) != BIND_EXPR)
+	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
+      else
+	poplevel (0, 0);
+    }
   if (flag_openmp)
     stmt = build2_loc (input_location, OMP_TARGET, void_type_node, stmt,
 		       omp_clauses);
--- a/gcc/gimplify.c	2015-03-20 13:39:32.000000000 +0100
+++ b/gcc/gimplify.c	2015-05-23 11:32:41.671037954 +0200
@@ -111,6 +111,9 @@
   /* Flag for GOVD_MAP: don't copy back.  */
   GOVD_MAP_TO_ONLY = 8192,
 
+  /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference.  */
+  GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 16384,
+
   GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
 			   | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
 			   | GOVD_LOCAL)
@@ -126,6 +129,7 @@
   ORT_TASK = 4,
   ORT_UNTIED_TASK = 5,
   ORT_TEAMS = 8,
+  ORT_COMBINED_TEAMS = 9,
   /* Data region.  */
   ORT_TARGET_DATA = 16,
   /* Data region with offloading.  */
@@ -5842,7 +5846,7 @@
 		     DECL_NAME (lang_hooks.decls.omp_report_decl (decl)));
 	      error_at (ctx->location, "enclosing task");
 	    }
-	  else if (ctx->region_type == ORT_TEAMS)
+	  else if (ctx->region_type & ORT_TEAMS)
 	    {
 	      error ("%qE not specified in enclosing teams construct",
 		     DECL_NAME (lang_hooks.decls.omp_report_decl (decl)));
@@ -5935,6 +5939,13 @@
      need to propagate anything to an outer context.  */
   if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
     return ret;
+  if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
+      == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
+    return ret;
+  if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
+		| GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
+      == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
+    return ret;
   if (ctx->outer_context
       && omp_notice_variable (ctx->outer_context, decl, in_code))
     return true;
@@ -6034,6 +6045,36 @@
   return false;
 }
 
+/* Return true if the CTX is combined with distribute and thus
+   lastprivate can't be supported.  */
+
+static bool
+omp_no_lastprivate (struct gimplify_omp_ctx *ctx)
+{
+  do
+    {
+      if (ctx->outer_context == NULL)
+	return false;
+      ctx = ctx->outer_context;
+      switch (ctx->region_type)
+	{
+	case ORT_WORKSHARE:
+	  if (!ctx->combined_loop)
+	    return false;
+	  if (ctx->distribute)
+	    return true;
+	  break;
+	case ORT_COMBINED_PARALLEL:
+	  break;
+	case ORT_COMBINED_TEAMS:
+	  return true;
+	default:
+	  return false;
+	}
+    }
+  while (1);
+}
+
 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
    and previous omp contexts.  */
 
@@ -6077,6 +6118,35 @@
 	case OMP_CLAUSE_LASTPRIVATE:
 	  flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
 	  check_non_private = "lastprivate";
+	  decl = OMP_CLAUSE_DECL (c);
+	  if (omp_no_lastprivate (ctx))
+	    {
+	      notice_outer = false;
+	      flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
+	    }
+	  else if (error_operand_p (decl))
+	    goto do_add;
+	  else if (outer_ctx
+		   && outer_ctx->region_type == ORT_COMBINED_PARALLEL
+		   && splay_tree_lookup (outer_ctx->variables,
+					 (splay_tree_key) decl) == NULL)
+	    omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
+	  else if (outer_ctx
+		   && outer_ctx->region_type == ORT_WORKSHARE
+		   && outer_ctx->combined_loop
+		   && splay_tree_lookup (outer_ctx->variables,
+					 (splay_tree_key) decl) == NULL
+		   && !omp_check_private (outer_ctx, decl, false))
+	    {
+	      omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
+	      if (outer_ctx->outer_context
+		  && (outer_ctx->outer_context->region_type
+		      == ORT_COMBINED_PARALLEL)
+		  && splay_tree_lookup (outer_ctx->outer_context->variables,
+					(splay_tree_key) decl) == NULL)
+		omp_add_variable (outer_ctx->outer_context, decl,
+				  GOVD_SHARED | GOVD_SEEN);
+	    }
 	  goto do_add;
 	case OMP_CLAUSE_REDUCTION:
 	  flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
@@ -6089,7 +6159,68 @@
 	      remove = true;
 	      break;
 	    }
+	  else
+	    {
+	      /* For combined #pragma omp parallel for simd, need to put
+		 lastprivate and perhaps firstprivate too on the
+		 parallel.  Similarly for #pragma omp for simd.  */
+	      struct gimplify_omp_ctx *octx = outer_ctx;
+	      decl = NULL_TREE;
+	      if (omp_no_lastprivate (ctx))
+		OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
+	      do
+		{
+		  if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+		      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+		    break;
+		  decl = OMP_CLAUSE_DECL (c);
+		  if (error_operand_p (decl))
+		    {
+		      decl = NULL_TREE;
+		      break;
+		    }
+		  if (octx
+		      && octx->region_type == ORT_WORKSHARE
+		      && octx->combined_loop)
+		    {
+		      if (octx->outer_context
+			  && (octx->outer_context->region_type
+			      == ORT_COMBINED_PARALLEL
+			      || (octx->outer_context->region_type
+				  == ORT_COMBINED_TEAMS)))
+			octx = octx->outer_context;
+		      else if (omp_check_private (octx, decl, false))
+			break;
+		    }
+		  else
+		    break;
+		  gcc_checking_assert (splay_tree_lookup (octx->variables,
+							  (splay_tree_key)
+							  decl) == NULL);
+		  flags = GOVD_SEEN;
+		  if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
+		    flags |= GOVD_FIRSTPRIVATE;
+		  if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+		    flags |= GOVD_LASTPRIVATE;
+		  omp_add_variable (octx, decl, flags);
+		  if (octx->outer_context == NULL)
+		    break;
+		  octx = octx->outer_context;
+		}
+	      while (1);
+	      if (octx
+		  && decl
+		  && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+		      || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
+		omp_notice_variable (octx, decl, true);
+	    }
 	  flags = GOVD_LINEAR | GOVD_EXPLICIT;
+	  if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+	      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+	    {
+	      notice_outer = false;
+	      flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
+	    }
 	  goto do_add;
 
 	case OMP_CLAUSE_MAP:
@@ -6543,34 +6674,6 @@
 		  OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
 		  OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
 		}
-	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
-		  && ctx->outer_context
-		  && !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
-		       && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
-		{
-		  if (ctx->outer_context->combined_loop
-		      && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
-		    {
-		      n = splay_tree_lookup (ctx->outer_context->variables,
-					     (splay_tree_key) decl);
-		      if (n == NULL
-			  || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
-			{
-			  int flags = GOVD_FIRSTPRIVATE;
-			  /* #pragma omp distribute does not allow
-			     lastprivate clause.  */
-			  if (!ctx->outer_context->distribute)
-			    flags |= GOVD_LASTPRIVATE;
-			  if (n == NULL)
-			    omp_add_variable (ctx->outer_context, decl,
-					      flags | GOVD_SEEN);
-			  else
-			    n->value |= flags | GOVD_SEEN;
-			}
-		    }
-		  else if (!is_global_var (decl))
-		    omp_notice_variable (ctx->outer_context, decl, true);
-		}
 	    }
 	  break;
 
@@ -6581,6 +6684,13 @@
 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
 	  OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
 	    = (n->value & GOVD_FIRSTPRIVATE) != 0;
+	  if (omp_no_lastprivate (ctx))
+	    {
+	      if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
+		remove = true;
+	      else
+		OMP_CLAUSE_CODE (c) = OMP_CLAUSE_PRIVATE;
+	    }
 	  break;
 
 	case OMP_CLAUSE_ALIGNED:
@@ -6895,6 +7005,22 @@
       gcc_unreachable ();
     }
 
+  /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
+     clause for the IV.  */
+  if (simd && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+    {
+      t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
+      gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
+      decl = TREE_OPERAND (t, 0);
+      for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
+	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+	    && OMP_CLAUSE_DECL (c) == decl)
+	  {
+	    OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
+	    break;
+	  }
+    }
+
   gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
 			     simd ? ORT_SIMD : ORT_WORKSHARE);
   if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
@@ -6969,38 +7095,67 @@
 	    {
 	      c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
 	      OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
-	      if (has_decl_expr
-		  && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
-		OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
+	      unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
+	      if ((has_decl_expr
+		   && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
+		  || omp_no_lastprivate (gimplify_omp_ctxp))
+		{
+		  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
+		  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
+		}
 	      OMP_CLAUSE_DECL (c) = decl;
 	      OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
 	      OMP_FOR_CLAUSES (for_stmt) = c;
-	      omp_add_variable (gimplify_omp_ctxp, decl,
-				GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
+	      
+	      omp_add_variable (gimplify_omp_ctxp, decl, flags);
+	      struct gimplify_omp_ctx *outer
+		= gimplify_omp_ctxp->outer_context;
+	      if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+		{
+		  if (outer->region_type == ORT_WORKSHARE
+		      && outer->combined_loop)
+		    {
+		      if (outer->outer_context
+			  && (outer->outer_context->region_type
+			      == ORT_COMBINED_PARALLEL))
+			outer = outer->outer_context;
+		      else if (omp_check_private (outer, decl, false))
+			outer = NULL;
+		    }
+		  else if (outer->region_type != ORT_COMBINED_PARALLEL)
+		    outer = NULL;
+		  if (outer)
+		    {
+		      omp_add_variable (outer, decl,
+					GOVD_LASTPRIVATE | GOVD_SEEN);
+		      if (outer->outer_context)
+			omp_notice_variable (outer->outer_context, decl, true);
+		    }
+		}
 	    }
 	  else
 	    {
 	      bool lastprivate
 		= (!has_decl_expr
-		   || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
-	      if (lastprivate
-		  && gimplify_omp_ctxp->outer_context
-		  && gimplify_omp_ctxp->outer_context->region_type
-		     == ORT_WORKSHARE
-		  && gimplify_omp_ctxp->outer_context->combined_loop
-		  && !gimplify_omp_ctxp->outer_context->distribute)
+		   || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
+		  && !omp_no_lastprivate (gimplify_omp_ctxp);
+	      struct gimplify_omp_ctx *outer
+		= gimplify_omp_ctxp->outer_context;
+	      if (outer && lastprivate)
 		{
-		  struct gimplify_omp_ctx *outer
-		    = gimplify_omp_ctxp->outer_context;
-		  n = splay_tree_lookup (outer->variables,
-					 (splay_tree_key) decl);
-		  if (n != NULL
-		      && (n->value & GOVD_DATA_SHARE_CLASS) == GOVD_LOCAL)
-		    lastprivate = false;
-		  else if (omp_check_private (outer, decl, false))
-		    error ("lastprivate variable %qE is private in outer "
-			   "context", DECL_NAME (decl));
-		  else
+		  if (outer->region_type == ORT_WORKSHARE
+		      && outer->combined_loop)
+		    {
+		      if (outer->outer_context
+			  && (outer->outer_context->region_type
+			      == ORT_COMBINED_PARALLEL))
+			outer = outer->outer_context;
+		      else if (omp_check_private (outer, decl, false))
+			outer = NULL;
+		    }
+		  else if (outer->region_type != ORT_COMBINED_PARALLEL)
+		    outer = NULL;
+		  if (outer)
 		    {
 		      omp_add_variable (outer, decl,
 					GOVD_LASTPRIVATE | GOVD_SEEN);
@@ -7008,6 +7163,7 @@
 			omp_notice_variable (outer->outer_context, decl, true);
 		    }
 		}
+
 	      c = build_omp_clause (input_location,
 				    lastprivate ? OMP_CLAUSE_LASTPRIVATE
 						: OMP_CLAUSE_PRIVATE);
@@ -7299,7 +7455,7 @@
       ort = ORT_TARGET_DATA;
       break;
     case OMP_TEAMS:
-      ort = ORT_TEAMS;
+      ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
       break;
     default:
       gcc_unreachable ();
--- a/gcc/ipa-chkp.c	2015-04-06 12:41:55.000000000 +0200
+++ b/gcc/ipa-chkp.c	2015-05-23 11:31:36.800208969 +0200
@@ -264,7 +264,7 @@
   if (!arg_type)
     return orig_type;
 
-  type = copy_node (orig_type);
+  type = build_distinct_type_copy (orig_type);
   TYPE_ARG_TYPES (type) = copy_list (TYPE_ARG_TYPES (type));
 
   for (arg_type = TYPE_ARG_TYPES (type);
--- a/gcc/ipa-inline.c	2015-04-03 20:09:13.000000000 +0200
+++ b/gcc/ipa-inline.c	2015-05-23 11:26:42.303067491 +0200
@@ -427,49 +427,55 @@
 	      && lookup_attribute ("always_inline",
 				   DECL_ATTRIBUTES (callee->decl)));
 
+     /* Until GCC 4.9 we did not check the semantics alterning flags
+	bellow and inline across optimization boundry.
+	Enabling checks bellow breaks several packages by refusing
+	to inline library always_inline functions. See PR65873.
+	Disable the check for early inlining for now until better solution
+	is found.  */
+     if (always_inline && early)
+	;
       /* There are some options that change IL semantics which means
          we cannot inline in these cases for correctness reason.
 	 Not even for always_inline declared functions.  */
       /* Strictly speaking only when the callee contains signed integer
          math where overflow is undefined.  */
-      if ((check_maybe_up (flag_strict_overflow)
-	   /* this flag is set by optimize.  Allow inlining across
-	      optimize boundary.  */
-	   && (!opt_for_fn (caller->decl, optimize)
-	       == !opt_for_fn (callee->decl, optimize) || !always_inline))
-	  || check_match (flag_wrapv)
-	  || check_match (flag_trapv)
-	  /* Strictly speaking only when the callee contains memory
-	     accesses that are not using alias-set zero anyway.  */
-	  || check_maybe_down (flag_strict_aliasing)
-	  /* Strictly speaking only when the callee uses FP math.  */
-	  || check_maybe_up (flag_rounding_math)
-	  || check_maybe_up (flag_trapping_math)
-	  || check_maybe_down (flag_unsafe_math_optimizations)
-	  || check_maybe_down (flag_finite_math_only)
-	  || check_maybe_up (flag_signaling_nans)
-	  || check_maybe_down (flag_cx_limited_range)
-	  || check_maybe_up (flag_signed_zeros)
-	  || check_maybe_down (flag_associative_math)
-	  || check_maybe_down (flag_reciprocal_math)
-	  /* We do not want to make code compiled with exceptions to be brought
-	     into a non-EH function unless we know that the callee does not
-	     throw.  This is tracked by DECL_FUNCTION_PERSONALITY.  */
-	  || (check_match (flag_non_call_exceptions)
-	      /* TODO: We also may allow bringing !flag_non_call_exceptions
-		 to flag_non_call_exceptions function, but that may need
-		 extra work in tree-inline to add the extra EH edges.  */
-	      && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
-		  || DECL_FUNCTION_PERSONALITY (callee->decl)))
-	  || (check_maybe_up (flag_exceptions)
-	      && DECL_FUNCTION_PERSONALITY (callee->decl))
-	  /* Strictly speaking only when the callee contains function
-	     calls that may end up setting errno.  */
-	  || check_maybe_up (flag_errno_math)
-	  /* When devirtualization is diabled for callee, it is not safe
-	     to inline it as we possibly mangled the type info.
-	     Allow early inlining of always inlines.  */
-	  || (!early && check_maybe_down (flag_devirtualize)))
+     else if ((check_maybe_up (flag_strict_overflow)
+	       /* this flag is set by optimize.  Allow inlining across
+		  optimize boundary.  */
+	       && (!opt_for_fn (caller->decl, optimize)
+		   == !opt_for_fn (callee->decl, optimize) || !always_inline))
+	      || check_match (flag_wrapv)
+	      || check_match (flag_trapv)
+	      /* Strictly speaking only when the callee uses FP math.  */
+	      || check_maybe_up (flag_rounding_math)
+	      || check_maybe_up (flag_trapping_math)
+	      || check_maybe_down (flag_unsafe_math_optimizations)
+	      || check_maybe_down (flag_finite_math_only)
+	      || check_maybe_up (flag_signaling_nans)
+	      || check_maybe_down (flag_cx_limited_range)
+	      || check_maybe_up (flag_signed_zeros)
+	      || check_maybe_down (flag_associative_math)
+	      || check_maybe_down (flag_reciprocal_math)
+	      /* We do not want to make code compiled with exceptions to be
+		 brought into a non-EH function unless we know that the callee
+		 does not throw.
+		 This is tracked by DECL_FUNCTION_PERSONALITY.  */
+	      || (check_match (flag_non_call_exceptions)
+		  /* TODO: We also may allow bringing !flag_non_call_exceptions
+		     to flag_non_call_exceptions function, but that may need
+		     extra work in tree-inline to add the extra EH edges.  */
+		  && (!opt_for_fn (callee->decl, flag_non_call_exceptions)
+		      || DECL_FUNCTION_PERSONALITY (callee->decl)))
+	      || (check_maybe_up (flag_exceptions)
+		  && DECL_FUNCTION_PERSONALITY (callee->decl))
+	      /* Strictly speaking only when the callee contains function
+		 calls that may end up setting errno.  */
+	      || check_maybe_up (flag_errno_math)
+	      /* When devirtualization is diabled for callee, it is not safe
+		 to inline it as we possibly mangled the type info.
+		 Allow early inlining of always inlines.  */
+	      || (!early && check_maybe_down (flag_devirtualize)))
 	{
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
@@ -484,6 +490,17 @@
 	  e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	  inlinable = false;
 	}
+      /* If explicit optimize attribute are not used, the mismatch is caused
+	 by different command line options used to build different units.
+	 Do not care about COMDAT functions - those are intended to be
+         optimized with the optimization flags of module they are used in.
+	 Also do not care about mixing up size/speed optimization when
+	 DECL_DISREGARD_INLINE_LIMITS is set.  */
+      else if ((callee->merged
+	        && !lookup_attribute ("optimize",
+				      DECL_ATTRIBUTES (caller->decl)))
+	       || DECL_DISREGARD_INLINE_LIMITS (callee->decl))
+	;
       /* If mismatch is caused by merging two LTO units with different
 	 optimizationflags we want to be bit nicer.  However never inline
 	 if one of functions is not optimized at all.  */
@@ -515,7 +532,7 @@
       else if (opt_for_fn (callee->decl, optimize_size)
 	       < opt_for_fn (caller->decl, optimize_size)
 	       || (opt_for_fn (callee->decl, optimize)
-		   >= opt_for_fn (caller->decl, optimize)))
+		   > opt_for_fn (caller->decl, optimize)))
 	{
 	  if (estimate_edge_time (e)
 	      >= 20 + inline_edge_summary (e)->call_stmt_time)
--- a/gcc/lra-constraints.c	2015-04-10 18:05:26.000000000 +0200
+++ b/gcc/lra-constraints.c	2015-05-23 11:18:33.964634884 +0200
@@ -533,7 +533,7 @@
   if (x == res || CONSTANT_P (res))
     return res;
   return lra_eliminate_regs_1 (insn, res, GET_MODE (res),
-			       0, false, false, true);
+			       false, false, 0, true);
 }
 
 /* Set up curr_operand_mode.  */
--- a/gcc/lra-eliminations.c	2015-02-04 21:02:21.000000000 +0100
+++ b/gcc/lra-eliminations.c	2015-05-23 11:18:33.965634942 +0200
@@ -318,7 +318,9 @@
    substitution if UPDATE_P, or the full offset if FULL_P, or
    otherwise zero.  If FULL_P, we also use the SP offsets for
    elimination to SP.  If UPDATE_P, use UPDATE_SP_OFFSET for updating
-   offsets of register elimnable to SP.
+   offsets of register elimnable to SP.  If UPDATE_SP_OFFSET is
+   non-zero, don't use difference of the offset and the previous
+   offset.
 
    MEM_MODE is the mode of an enclosing MEM.  We need this to know how
    much to adjust a register for, e.g., PRE_DEC.  Also, if we are
@@ -341,7 +343,8 @@
   const char *fmt;
   int copied = 0;
 
-  gcc_assert (!update_p || !full_p);
+  lra_assert (!update_p || !full_p);
+  lra_assert (update_sp_offset == 0 || (!subst_p && update_p && !full_p));
   if (! current_function_decl)
     return x;
 
@@ -366,11 +369,14 @@
 	{
 	  rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
 
-	  if (update_p)
-	    return plus_constant (Pmode, to,
-				  ep->offset - ep->previous_offset
-				  + (ep->to_rtx == stack_pointer_rtx
-				     ? update_sp_offset : 0));
+	  if (update_sp_offset != 0)
+	    {
+	      if (ep->to_rtx == stack_pointer_rtx)
+		return plus_constant (Pmode, to, update_sp_offset);
+	      return to;
+	    }
+	  else if (update_p)
+	    return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
 	  else if (full_p)
 	    return plus_constant (Pmode, to,
 				  ep->offset
@@ -395,16 +401,15 @@
 
 	      if (! update_p && ! full_p)
 		return gen_rtx_PLUS (Pmode, to, XEXP (x, 1));
-
-	      offset = (update_p
-			? ep->offset - ep->previous_offset
-			+ (ep->to_rtx == stack_pointer_rtx
-			   ? update_sp_offset : 0)
-			: ep->offset);
+	      
+	      if (update_sp_offset != 0)
+		offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
+	      else
+		offset = (update_p
+			  ? ep->offset - ep->previous_offset : ep->offset);
 	      if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
 		offset -= lra_get_insn_recog_data (insn)->sp_offset;
-	      if (CONST_INT_P (XEXP (x, 1))
-		  && INTVAL (XEXP (x, 1)) == -offset)
+	      if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == -offset)
 		return to;
 	      else
 		return gen_rtx_PLUS (Pmode, to,
@@ -451,12 +456,18 @@
 	{
 	  rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
 
-	  if (update_p)
+	  if (update_sp_offset != 0)
+	    {
+	      if (ep->to_rtx == stack_pointer_rtx)
+		return plus_constant (Pmode,
+				      gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
+				      update_sp_offset * INTVAL (XEXP (x, 1)));
+	      return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
+	    }
+	  else if (update_p)
 	    return plus_constant (Pmode,
 				  gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
-				  (ep->offset - ep->previous_offset
-				   + (ep->to_rtx == stack_pointer_rtx
-				      ? update_sp_offset : 0))
+				  (ep->offset - ep->previous_offset)
 				  * INTVAL (XEXP (x, 1)));
 	  else if (full_p)
 	    {
@@ -889,11 +900,12 @@
 
    If REPLACE_P is false, just update the offsets while keeping the
    base register the same.  If FIRST_P, use the sp offset for
-   elimination to sp.  Otherwise, use UPDATE_SP_OFFSET for this.
-   Attach the note about used elimination for insns setting frame
-   pointer to update elimination easy (without parsing already
-   generated elimination insns to find offset previously used) in
-   future.  */
+   elimination to sp.  Otherwise, use UPDATE_SP_OFFSET for this.  If
+   UPDATE_SP_OFFSET is non-zero, don't use difference of the offset
+   and the previous offset.  Attach the note about used elimination
+   for insns setting frame pointer to update elimination easy (without
+   parsing already generated elimination insns to find offset
+   previously used) in future.  */
 
 void
 eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
@@ -940,6 +952,10 @@
 		rtx src = SET_SRC (old_set);
 		rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx);
 		
+		/* We should never process such insn with non-zero
+		   UPDATE_SP_OFFSET.  */
+		lra_assert (update_sp_offset == 0);
+		
 		if (off != NULL_RTX
 		    || src == ep->to_rtx
 		    || (GET_CODE (src) == PLUS
@@ -1026,7 +1042,8 @@
 
 	  if (! replace_p)
 	    {
-	      offset += (ep->offset - ep->previous_offset);
+	      if (update_sp_offset == 0)
+		offset += (ep->offset - ep->previous_offset);
 	      if (ep->to_rtx == stack_pointer_rtx)
 		{
 		  if (first_p)
--- a/gcc/lra-spills.c	2015-01-15 14:28:42.000000000 +0100
+++ b/gcc/lra-spills.c	2015-05-23 11:18:33.965634942 +0200
@@ -461,7 +461,7 @@
 	{
 	  rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem,
 					GET_MODE (pseudo_slots[i].mem),
-					0, false, false, true);
+					false, false, 0, true);
 	  *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x);
 	}
       return;
--- a/gcc/lto-wrapper.c	2015-01-30 17:15:00.000000000 +0100
+++ b/gcc/lto-wrapper.c	2015-05-23 11:21:27.938957086 +0200
@@ -934,7 +934,7 @@
 	  filename[p - argv[i]] = '\0';
 	  file_offset = (off_t) loffset;
 	}
-      fd = open (argv[i], O_RDONLY);
+      fd = open (filename, O_RDONLY | O_BINARY);
       if (fd == -1)
 	{
 	  lto_argv[lto_argc++] = argv[i];
--- a/gcc/match.pd	2015-02-13 21:17:55.000000000 +0100
+++ b/gcc/match.pd	2015-05-23 11:33:11.742416376 +0200
@@ -702,16 +702,12 @@
       (for integers).  Avoid this if the final type is a pointer since
       then we sometimes need the middle conversion.  Likewise if the
       final type has a precision not equal to the size of its mode.  */
-   (if (((inter_int && inside_int)
-	 || (inter_float && inside_float)
-	 || (inter_vec && inside_vec))
+   (if (((inter_int && inside_int) || (inter_float && inside_float))
+	&& (final_int || final_float)
 	&& inter_prec >= inside_prec
-	&& (inter_float || inter_vec
-	    || inter_unsignedp == inside_unsignedp)
-	&& ! (final_prec != GET_MODE_PRECISION (element_mode (type))
-	      && element_mode (type) == element_mode (inter_type))
-	&& ! final_ptr
-	&& (! final_vec || inter_prec == inside_prec))
+	&& (inter_float || inter_unsignedp == inside_unsignedp)
+	&& ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
+	      && TYPE_MODE (type) == TYPE_MODE (inter_type)))
     (ocvt @0))
 
    /* If we have a sign-extension of a zero-extended value, we can
--- a/gcc/omp-low.c	2015-04-03 15:35:49.000000000 +0200
+++ b/gcc/omp-low.c	2015-05-23 11:32:41.672037967 +0200
@@ -5377,7 +5377,10 @@
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
 
   entry_bb = region->entry;
-  exit_bb = region->exit;
+  if (gimple_code (entry_stmt) == GIMPLE_OMP_TASK)
+    exit_bb = region->cont;
+  else
+    exit_bb = region->exit;
 
   bool is_cilk_for
     = (flag_cilkplus
@@ -5436,7 +5439,9 @@
 	 variable.  In which case, we need to keep the assignment.  */
       if (gimple_omp_taskreg_data_arg (entry_stmt))
 	{
-	  basic_block entry_succ_bb = single_succ (entry_bb);
+	  basic_block entry_succ_bb
+	    = single_succ_p (entry_bb) ? single_succ (entry_bb)
+				       : FALLTHRU_EDGE (entry_bb)->dest;
 	  tree arg, narg;
 	  gimple parcopy_stmt = NULL;
 
@@ -5524,14 +5529,28 @@
       e = split_block (entry_bb, stmt);
       gsi_remove (&gsi, true);
       entry_bb = e->dest;
-      single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+      edge e2 = NULL;
+      if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
+	single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+      else
+	{
+	  e2 = make_edge (e->src, BRANCH_EDGE (entry_bb)->dest, EDGE_ABNORMAL);
+	  gcc_assert (e2->dest == region->exit);
+	  remove_edge (BRANCH_EDGE (entry_bb));
+	  set_immediate_dominator (CDI_DOMINATORS, e2->dest, e->src);
+	  gsi = gsi_last_bb (region->exit);
+	  gcc_assert (!gsi_end_p (gsi)
+		      && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+	  gsi_remove (&gsi, true);
+	}
 
-      /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR.  */
+      /* Convert GIMPLE_OMP_{RETURN,CONTINUE} into a RETURN_EXPR.  */
       if (exit_bb)
 	{
 	  gsi = gsi_last_bb (exit_bb);
 	  gcc_assert (!gsi_end_p (gsi)
-		      && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+		      && (gimple_code (gsi_stmt (gsi))
+			  == (e2 ? GIMPLE_OMP_CONTINUE : GIMPLE_OMP_RETURN)));
 	  stmt = gimple_build_return (NULL);
 	  gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
 	  gsi_remove (&gsi, true);
@@ -5552,6 +5571,14 @@
       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
       if (exit_bb)
 	single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
+      if (e2)
+	{
+	  basic_block dest_bb = e2->dest;
+	  if (!exit_bb)
+	    make_edge (new_bb, dest_bb, EDGE_FALLTHRU);
+	  remove_edge (e2);
+	  set_immediate_dominator (CDI_DOMINATORS, dest_bb, new_bb);
+	}
       /* When the OMP expansion process cannot guarantee an up-to-date
          loop tree arrange for the child function to fixup loops.  */
       if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
@@ -10511,7 +10538,21 @@
 	cond_code = EQ_EXPR;
     }
 
-  cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
+  tree n2 = fd->loop.n2;
+  if (fd->collapse > 1
+      && TREE_CODE (n2) != INTEGER_CST
+      && gimple_omp_for_combined_into_p (fd->for_stmt)
+      && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
+    {
+      gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
+      if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR)
+	{
+	  struct omp_for_data outer_fd;
+	  extract_omp_for_data (gfor, &outer_fd, NULL);
+	  n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
+	}
+    }
+  cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);
 
   clauses = gimple_omp_for_clauses (fd->for_stmt);
   stmts = NULL;
@@ -11158,6 +11199,10 @@
     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
   gimple_seq_add_seq (&new_body, par_olist);
   new_body = maybe_catch_exception (new_body);
+  if (gimple_code (stmt) == GIMPLE_OMP_TASK)
+    gimple_seq_add_stmt (&new_body,
+			 gimple_build_omp_continue (integer_zero_node,
+						    integer_zero_node));
   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
   gimple_omp_set_body (stmt, new_body);
 
@@ -12272,6 +12317,10 @@
 	 somewhere other than the next block.  This will be
 	 created later.  */
       cur_region->exit = bb;
+      if (cur_region->type == GIMPLE_OMP_TASK)
+	/* Add an edge corresponding to not scheduling the task
+	   immediately.  */
+	make_edge (cur_region->entry, bb, EDGE_ABNORMAL);
       fallthru = cur_region->type != GIMPLE_OMP_SECTION;
       cur_region = cur_region->outer;
       break;
@@ -12320,6 +12369,10 @@
 	  }
 	  break;
 
+	case GIMPLE_OMP_TASK:
+	  fallthru = true;
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
--- a/gcc/tree.h	2015-04-08 20:41:55.000000000 +0200
+++ b/gcc/tree.h	2015-05-23 11:32:41.673037980 +0200
@@ -1320,6 +1320,11 @@
 #define OMP_PARALLEL_COMBINED(NODE) \
   (OMP_PARALLEL_CHECK (NODE)->base.private_flag)
 
+/* True on an OMP_TEAMS statement if it represents an explicit
+   combined teams distribute constructs.  */
+#define OMP_TEAMS_COMBINED(NODE) \
+  (OMP_TEAMS_CHECK (NODE)->base.private_flag)
+
 /* True if OMP_ATOMIC* is supposed to be sequentially consistent
    as opposed to relaxed.  */
 #define OMP_ATOMIC_SEQ_CST(NODE) \
--- a/gcc/tree-vrp.c	2015-02-17 16:32:05.000000000 +0100
+++ b/gcc/tree-vrp.c	2015-05-23 11:18:33.967635057 +0200
@@ -874,13 +874,18 @@
   if (is_new)
     {
       /* Do not allow transitions up the lattice.  The following
-         is slightly more awkward than just new_vr->type < old_vr->type
+	 is slightly more awkward than just new_vr->type < old_vr->type
 	 because VR_RANGE and VR_ANTI_RANGE need to be considered
 	 the same.  We may not have is_new when transitioning to
-	 UNDEFINED or from VARYING.  */
-      if (new_vr->type == VR_UNDEFINED
-	  || old_vr->type == VR_VARYING)
-	set_value_range_to_varying (old_vr);
+	 UNDEFINED.  If old_vr->type is VARYING, we shouldn't be
+	 called.  */
+      if (new_vr->type == VR_UNDEFINED)
+	{
+	  BITMAP_FREE (new_vr->equiv);
+	  set_value_range_to_varying (old_vr);
+	  set_value_range_to_varying (new_vr);
+	  return true;
+	}
       else
 	set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
 			 new_vr->equiv);
@@ -8949,6 +8954,9 @@
 	  fprintf (dump_file, "\n");
 	}
 
+      if (vr_result.type == VR_VARYING)
+	return SSA_PROP_VARYING;
+
       return SSA_PROP_INTERESTING;
     }
 
--- a/gcc/ubsan.c	2015-04-09 21:51:08.000000000 +0200
+++ b/gcc/ubsan.c	2015-05-23 11:22:23.302098186 +0200
@@ -87,6 +87,7 @@
 #include "builtins.h"
 #include "tree-object-size.h"
 #include "tree-eh.h"
+#include "tree-cfg.h"
 
 /* Map from a tree to a VAR_DECL tree.  */
 
@@ -1420,7 +1421,7 @@
       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
     return;
 
-  bool can_throw = stmt_could_throw_p (stmt);
+  bool ends_bb = stmt_ends_bb_p (stmt);
   location_t loc = gimple_location (stmt);
   tree lhs = gimple_assign_lhs (stmt);
   tree ptype = build_pointer_type (TREE_TYPE (rhs));
@@ -1432,7 +1433,7 @@
   tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
 		     build_int_cst (atype, 0));
   tree urhs = make_ssa_name (utype);
-  if (can_throw)
+  if (ends_bb)
     {
       gimple_assign_set_lhs (stmt, urhs);
       g = gimple_build_assign (lhs, NOP_EXPR, urhs);
@@ -1469,7 +1470,7 @@
   gimple_set_location (g, loc);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  if (!can_throw)
+  if (!ends_bb)
     {
       gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
       update_stmt (stmt);
--- a/libstdc++-v3/include/debug/vector	2015-01-05 13:33:28.000000000 +0100
+++ b/libstdc++-v3/include/debug/vector	2015-05-23 11:18:33.967635057 +0200
@@ -69,13 +69,17 @@
 
       _Safe_vector&
       operator=(const _Safe_vector&) noexcept
-      { _M_update_guaranteed_capacity(); }
+      {
+	_M_update_guaranteed_capacity();
+	return *this;
+      }
 
       _Safe_vector&
       operator=(_Safe_vector&& __x) noexcept
       {
 	_M_update_guaranteed_capacity();
 	__x._M_guaranteed_capacity = 0;
+	return *this;
       }
 #endif
 
--- a/libstdc++-v3/include/experimental/any	2015-01-05 13:33:28.000000000 +0100
+++ b/libstdc++-v3/include/experimental/any	2015-05-23 11:20:55.285156612 +0200
@@ -94,7 +94,7 @@
       std::aligned_storage<sizeof(_M_ptr), sizeof(_M_ptr)>::type _M_buffer;
     };
 
-    template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
+    template<typename _Tp, typename _Safe = is_trivially_copyable<_Tp>,
 	     bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))>
       using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;
 
--- a/libstdc++-v3/include/std/limits	2015-01-05 13:33:28.000000000 +0100
+++ b/libstdc++-v3/include/std/limits	2015-05-23 11:22:05.903763794 +0200
@@ -1490,7 +1490,8 @@
       min() _GLIBCXX_USE_NOEXCEPT { return 0; } 				\
  										\
       static _GLIBCXX_CONSTEXPR unsigned TYPE 					\
-      max() _GLIBCXX_USE_NOEXCEPT { return  __glibcxx_max_b (TYPE, BITSIZE); }  \
+      max() _GLIBCXX_USE_NOEXCEPT						\
+      { return  __glibcxx_max_b (unsigned TYPE, BITSIZE); }			\
  										\
       UEXT									\
  										\
