[lfs-patches] r3355 - in trunk: bash binutils gcc glibc mpfr

bdubbs at higgs.linuxfromscratch.org bdubbs at higgs.linuxfromscratch.org
Tue Feb 16 14:59:58 PST 2016


Author: bdubbs
Date: Tue Feb 16 14:59:58 2016
New Revision: 3355

Log:
Upstream patches for LFS

Added:
   trunk/bash/bash-4.3.30-upstream_fixes-3.patch
   trunk/binutils/binutils-2.26-upstream_fix-2.patch
   trunk/gcc/gcc-5.3.0-upstream_fixes-1.patch
   trunk/glibc/glibc-2.22-upstream_fixes-1.patch
   trunk/mpfr/mpfr-3.1.3-upstream_fixes-2.patch   (contents, props changed)

Added: trunk/bash/bash-4.3.30-upstream_fixes-3.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/bash/bash-4.3.30-upstream_fixes-3.patch	Tue Feb 16 14:59:58 2016	(r3355)
@@ -0,0 +1,488 @@
+Submitted By:            Armin K. <krejzi at email dot com>
+Date:                    2016-02-16
+Initial Package Version: 4.3
+Upstream Status:         Already in upstream patch repo
+Origin:                  Upstream
+Description:             This patch contains upstream patch numbers 031 thru 042
+
+--- a/arrayfunc.c	2014-10-01 18:57:35.000000000 +0200
++++ b/arrayfunc.c	2015-09-06 22:57:56.328941059 +0200
+@@ -404,6 +404,9 @@
+       (*var->assign_func) (var, l->word->word, i, 0);
+     else
+       array_insert (a, i, l->word->word);
++
++  VUNSETATTR (var, att_invisible);	/* no longer invisible */
++
+   return var;
+ }
+ 
+@@ -634,6 +637,10 @@
+ 
+   if (nlist)
+     dispose_words (nlist);
++
++  if (var)
++    VUNSETATTR (var, att_invisible);	/* no longer invisible */
++
+   return (var);
+ }
+ 
+--- a/assoc.c	2011-11-05 21:39:05.000000000 +0100
++++ b/assoc.c	2015-09-06 22:57:56.328941059 +0200
+@@ -436,6 +436,8 @@
+ #if 1
+ 	if (sh_contains_shell_metas (tlist->key))
+ 	  istr = sh_double_quote (tlist->key);
++	else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0')
++	  istr = sh_double_quote (tlist->key);	
+ 	else
+ 	  istr = tlist->key;	
+ #else
+--- a/bashline.c	2014-10-01 18:57:30.000000000 +0200
++++ b/bashline.c	2015-09-06 22:58:34.711768943 +0200
+@@ -202,6 +202,7 @@
+ extern int last_command_exit_value;
+ extern int array_needs_making;
+ extern int posixly_correct, no_symbolic_links;
++extern int sigalrm_seen;
+ extern char *current_prompt_string, *ps1_prompt;
+ extern STRING_INT_ALIST word_token_alist[];
+ extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
+@@ -1467,10 +1468,23 @@
+ 
+       os = start;
+       n = 0;
++      was_assignment = 0;
+       s = find_cmd_start (os);
+       e = find_cmd_end (end);
+       do
+ 	{
++	  /* Don't read past the end of rl_line_buffer */
++	  if (s > rl_end)
++	    {
++	      s1 = s = e1;
++	      break;
++	    }
++	  /* Or past point if point is within an assignment statement */
++	  else if (was_assignment && s > rl_point)
++	    {
++	      s1 = s = e1;
++	      break;
++	    }
+ 	  /* Skip over assignment statements preceding a command name.  If we
+ 	     don't find a command name at all, we can perform command name
+ 	     completion.  If we find a partial command name, we should perform
+@@ -4208,8 +4222,9 @@
+ {
+   /* If we're going to longjmp to top_level, make sure we clean up readline.
+      check_signals will call QUIT, which will eventually longjmp to top_level,
+-     calling run_interrupt_trap along the way. */
+-  if (interrupt_state)
++     calling run_interrupt_trap along the way.  The check for sigalrm_seen is
++     to clean up the read builtin's state. */
++  if (terminating_signal || interrupt_state || sigalrm_seen)
+     rl_cleanup_after_signal ();
+   bashline_reset_event_hook ();
+   check_signals_and_traps ();	/* XXX */
+--- a/builtins/common.h	2014-10-01 18:57:47.000000000 +0200
++++ b/builtins/common.h	2015-09-06 22:57:56.330941103 +0200
+@@ -122,6 +122,10 @@
+ /* Functions from getopts.def */
+ extern void getopts_reset __P((int));
+ 
++/* Functions from read.def */
++extern void read_tty_cleanup __P((void));
++extern int read_tty_modified __P((void));
++
+ /* Functions from set.def */
+ extern int minus_o_option_value __P((char *));
+ extern void list_minus_o_opts __P((int, int));
+--- a/builtins/read.def	2014-10-01 18:57:38.000000000 +0200
++++ b/builtins/read.def	2015-09-06 22:57:56.335941212 +0200
+@@ -140,10 +140,12 @@
+ procenv_t alrmbuf;
+ int sigalrm_seen;
+ 
+-static int reading;
++static int reading, tty_modified;
+ static SigHandler *old_alrm;
+ static unsigned char delim;
+ 
++static struct ttsave termsave;
++
+ /* In all cases, SIGALRM just sets a flag that we check periodically.  This
+    avoids problems with the semi-tricky stuff we do with the xfree of
+    input_string at the top of the unwind-protect list (see below). */
+@@ -188,7 +190,6 @@
+   struct stat tsb;
+   SHELL_VAR *var;
+   TTYSTRUCT ttattrs, ttset;
+-  struct ttsave termsave;
+ #if defined (ARRAY_VARS)
+   WORD_LIST *alist;
+ #endif
+@@ -221,7 +222,7 @@
+   USE_VAR(ps2);
+   USE_VAR(lastsig);
+ 
+-  sigalrm_seen = reading = 0;
++  sigalrm_seen = reading = tty_modified = 0;
+ 
+   i = 0;		/* Index into the string that we are reading. */
+   raw = edit = 0;	/* Not reading raw input by default. */
+@@ -438,6 +439,8 @@
+ 	  retval = 128+SIGALRM;
+ 	  goto assign_vars;
+ 	}
++      if (interactive_shell == 0)
++	initialize_terminating_signals ();
+       old_alrm = set_signal_handler (SIGALRM, sigalrm);
+       add_unwind_protect (reset_alarm, (char *)NULL);
+ #if defined (READLINE)
+@@ -482,7 +485,10 @@
+ 	  i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset);
+ 	  if (i < 0)
+ 	    sh_ttyerror (1);
++	  tty_modified = 1;
+ 	  add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
++	  if (interactive_shell == 0)
++	    initialize_terminating_signals ();
+ 	}
+     }
+   else if (silent)	/* turn off echo but leave term in canonical mode */
+@@ -497,7 +503,10 @@
+       if (i < 0)
+ 	sh_ttyerror (1);
+ 
++      tty_modified = 1;
+       add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
++      if (interactive_shell == 0)
++	initialize_terminating_signals ();
+     }
+ 
+   /* This *must* be the top unwind-protect on the stack, so the manipulation
+@@ -588,6 +597,8 @@
+ 	    }
+ 	  else
+ 	    lastsig = 0;
++	  if (terminating_signal && tty_modified)
++	    ttyrestore (&termsave);	/* fix terminal before exiting */
+ 	  CHECK_TERMSIG;
+ 	  eof = 1;
+ 	  break;
+@@ -978,6 +989,20 @@
+      struct ttsave *ttp;
+ {
+   ttsetattr (ttp->fd, ttp->attrs);
++  tty_modified = 0;
++}
++
++void
++read_tty_cleanup ()
++{
++  if (tty_modified)
++    ttyrestore (&termsave);
++}
++
++int
++read_tty_modified ()
++{
++  return (tty_modified);
+ }
+ 
+ #if defined (READLINE)
+--- a/builtins/set.def	2013-04-19 13:20:34.000000000 +0200
++++ b/builtins/set.def	2015-09-06 22:57:56.336941234 +0200
+@@ -751,9 +751,11 @@
+   WORD_LIST *list;
+ {
+   int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
++  int global_unset_func, global_unset_var;
+   char *name;
+ 
+   unset_function = unset_variable = unset_array = nameref = any_failed = 0;
++  global_unset_func = global_unset_var = 0;
+ 
+   reset_internal_getopt ();
+   while ((opt = internal_getopt (list, "fnv")) != -1)
+@@ -761,10 +763,10 @@
+       switch (opt)
+ 	{
+ 	case 'f':
+-	  unset_function = 1;
++	  global_unset_func = 1;
+ 	  break;
+ 	case 'v':
+-	  unset_variable = 1;
++	  global_unset_var = 1;
+ 	  break;
+ 	case 'n':
+ 	  nameref = 1;
+@@ -777,7 +779,7 @@
+ 
+   list = loptend;
+ 
+-  if (unset_function && unset_variable)
++  if (global_unset_func && global_unset_var)
+     {
+       builtin_error (_("cannot simultaneously unset a function and a variable"));
+       return (EXECUTION_FAILURE);
+@@ -795,6 +797,9 @@
+ 
+       name = list->word->word;
+ 
++      unset_function = global_unset_func;
++      unset_variable = global_unset_var;
++
+ #if defined (ARRAY_VARS)
+       unset_array = 0;
+       if (!unset_function && valid_array_reference (name))
+--- a/jobs.c	2014-10-01 18:57:26.000000000 +0200
++++ b/jobs.c	2015-09-06 22:57:56.340941321 +0200
+@@ -3339,7 +3339,9 @@
+       if (posixly_correct && this_shell_builtin && this_shell_builtin == wait_builtin)
+ 	{
+ 	  interrupt_immediately = 0;
+-	  trap_handler (SIGCHLD);	/* set pending_traps[SIGCHLD] */
++	  /* This was trap_handler (SIGCHLD) but that can lose traps if
++	     children_exited > 1 */
++	  queue_sigchld_trap (children_exited);
+ 	  wait_signal_received = SIGCHLD;
+ 	  /* If we're in a signal handler, let CHECK_WAIT_INTR pick it up;
+ 	     run_pending_traps will call run_sigchld_trap later  */
+--- a/lib/readline/complete.c	2013-10-14 15:27:10.000000000 +0200
++++ b/lib/readline/complete.c	2015-09-06 22:58:34.712768964 +0200
+@@ -689,6 +689,8 @@
+ 
+   if (temp == 0 || *temp == '\0')
+     return (pathname);
++  else if (temp[1] == 0 && temp == pathname)
++    return (pathname);
+   /* If the basename is NULL, we might have a pathname like '/usr/src/'.
+      Look for a previous slash and, if one is found, return the portion
+      following that slash.  If there's no previous slash, just return the
+--- a/lib/sh/unicode.c	2014-01-30 22:47:19.000000000 +0100
++++ b/lib/sh/unicode.c	2015-09-06 22:57:56.341941343 +0200
+@@ -78,13 +78,15 @@
+   s = strrchr (locale, '.');
+   if (s)
+     {
+-      strcpy (charsetbuf, s+1);
++      strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1);
++      charsetbuf[sizeof (charsetbuf) - 1] = '\0';
+       t = strchr (charsetbuf, '@');
+       if (t)
+ 	*t = 0;
+       return charsetbuf;
+     }
+-  strcpy (charsetbuf, locale);
++  strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1);
++  charsetbuf[sizeof (charsetbuf) - 1] = '\0';
+   return charsetbuf;
+ }
+ #endif
+--- a/parse.y	2014-10-05 19:52:50.000000000 +0200
++++ b/parse.y	2015-09-06 22:58:35.245780313 +0200
+@@ -2818,11 +2818,16 @@
+     case AND_AND:
+     case OR_OR:
+     case '&':
++    case WHILE:
+     case DO:
++    case UNTIL:
++    case IF:
+     case THEN:
++    case ELIF:
+     case ELSE:
+     case '{':		/* } */
+-    case '(':		/* ) */
++    case '(':		/* )( */
++    case ')':		/* only valid in case statement */
+     case BANG:		/* ! time pipeline */
+     case TIME:		/* time time pipeline */
+     case TIMEOPT:	/* time -p time pipeline */
+@@ -3703,6 +3708,8 @@
+ /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
+ 	      tflags |= LEX_INWORD;
+ 	      lex_wlen = 0;
++	      if (tflags & LEX_RESWDOK)
++		lex_rwlen = 0;
+ 	    }
+ 	}
+ 
+--- a/patchlevel.h	2014-10-05 19:52:50.000000000 +0200
++++ b/patchlevel.h	2015-09-06 22:58:35.248780377 +0200
+@@ -25,6 +25,6 @@
+    regexp `^#define[ 	]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+ 
+-#define PATCHLEVEL 30
++#define PATCHLEVEL 42
+ 
+ #endif /* _PATCHLEVEL_H_ */
+--- a/shell.c	2014-01-14 14:04:32.000000000 +0100
++++ b/shell.c	2015-09-06 22:57:56.343941387 +0200
+@@ -73,6 +73,7 @@
+ #endif
+ 
+ #if defined (READLINE)
++#  include <readline/readline.h>
+ #  include "bashline.h"
+ #endif
+ 
+@@ -909,6 +910,14 @@
+   fflush (stdout);		/* XXX */
+   fflush (stderr);
+ 
++  /* Clean up the terminal if we are in a state where it's been modified. */
++#if defined (READLINE)
++  if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
++    (*rl_deprep_term_function) ();
++#endif
++  if (read_tty_modified ())
++    read_tty_cleanup ();
++
+   /* Do trap[0] if defined.  Allow it to override the exit status
+      passed to us. */
+   if (signal_is_trapped (0))
+--- a/sig.c	2014-01-10 21:06:06.000000000 +0100
++++ b/sig.c	2015-09-06 22:57:56.344941408 +0200
+@@ -532,8 +532,10 @@
+ #if defined (READLINE)
+   /* Set the event hook so readline will call it after the signal handlers
+      finish executing, so if this interrupted character input we can get
+-     quick response. */
+-  if (interactive_shell && interactive && no_line_editing == 0)
++     quick response.  If readline is active or has modified the terminal we
++     need to set this no matter what the signal is, though the check for
++     RL_STATE_TERMPREPPED is possibly redundant. */
++  if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE (RL_STATE_TERMPREPPED))
+     bashline_set_event_hook ();
+ #endif
+ 
+--- a/subst.c	2014-10-01 18:57:47.000000000 +0200
++++ b/subst.c	2015-09-06 22:58:34.177757570 +0200
+@@ -5782,7 +5782,7 @@
+       /* XXX - does this leak if name[@] or name[*]? */
+       if (pflags & PF_ASSIGNRHS)
+         {
+-          temp = array_variable_name (name, &tt, (int *)0);
++          var = array_variable_part (name, &tt, (int *)0);
+           if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
+ 	    temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype, &ind);
+ 	  else
+--- a/subst.h	2014-10-01 18:57:43.000000000 +0200
++++ b/subst.h	2015-09-06 22:57:56.344941408 +0200
+@@ -47,6 +47,7 @@
+ #define ASS_MKASSOC	0x0004
+ #define ASS_MKGLOBAL	0x0008	/* force global assignment */
+ #define ASS_NAMEREF	0x0010	/* assigning to nameref variable */
++#define ASS_FROMREF	0x0020	/* assigning from value of nameref variable */
+ 
+ /* Flags for the string extraction functions. */
+ #define SX_NOALLOC	0x0001	/* just skip; don't return substring */
+--- a/variables.c	2014-10-01 18:57:51.000000000 +0200
++++ b/variables.c	2015-09-06 22:57:56.345941430 +0200
+@@ -2516,10 +2516,27 @@
+      HASH_TABLE *table;
+      int hflags, aflags;
+ {
+-  char *newval;
++  char *newname, *newval;
+   SHELL_VAR *entry;
++#if defined (ARRAY_VARS)
++  arrayind_t ind;
++  char *subp;
++  int sublen;
++#endif
+ 
++  newname = 0;
++#if defined (ARRAY_VARS)
++  if ((aflags & ASS_FROMREF) && (hflags & HASH_NOSRCH) == 0 && valid_array_reference (name))
++    {
++      newname = array_variable_name (name, &subp, &sublen);
++      if (newname == 0)
++	return (SHELL_VAR *)NULL;	/* XXX */
++      entry = hash_lookup (newname, table);
++    }
++  else
++#endif
+   entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
++
+   /* Follow the nameref chain here if this is the global variables table */
+   if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
+     {
+@@ -2550,6 +2567,16 @@
+       var_setvalue (entry, make_variable_value (entry, value, 0));
+       }
+     }
++#if defined (ARRAY_VARS)
++  else if (entry == 0 && newname)
++    {
++      entry = make_new_array_variable (newname);	/* indexed array by default */
++      if (entry == 0)
++	return entry;
++      ind = array_expand_index (name, subp, sublen);
++      bind_array_element (entry, ind, value, aflags);
++    }
++#endif
+   else if (entry == 0)
+     {
+       entry = make_new_variable (name, table);
+@@ -2670,7 +2697,8 @@
+ 			 normal. */
+ 		      if (nameref_cell (nv) == 0)
+ 			return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
+-		      return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
++		      /* XXX - bug here with ref=array[index] */
++		      return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags|ASS_FROMREF));
+ 		    }
+ 		  else
+ 		    v = nv;
+@@ -2805,10 +2833,12 @@
+ #endif
+     v = bind_variable (lhs, rhs, 0);
+ 
+-  if (v && isint)
+-    VSETATTR (v, att_integer);
+-
+-  VUNSETATTR (v, att_invisible);
++  if (v)
++    {
++      if (isint)
++	VSETATTR (v, att_integer);
++      VUNSETATTR (v, att_invisible);
++    }
+ 
+   return (v);
+ }
+--- a/y.tab.c	2014-10-05 19:52:50.000000000 +0200
++++ b/y.tab.c	2015-09-06 22:58:35.247780356 +0200
+@@ -5130,11 +5130,16 @@
+     case AND_AND:
+     case OR_OR:
+     case '&':
++    case WHILE:
+     case DO:
++    case UNTIL:
++    case IF:
+     case THEN:
++    case ELIF:
+     case ELSE:
+     case '{':		/* } */
+-    case '(':		/* ) */
++    case '(':		/* )( */
++    case ')':		/* only valid in case statement */
+     case BANG:		/* ! time pipeline */
+     case TIME:		/* time time pipeline */
+     case TIMEOPT:	/* time -p time pipeline */
+@@ -6015,6 +6020,8 @@
+ /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
+ 	      tflags |= LEX_INWORD;
+ 	      lex_wlen = 0;
++	      if (tflags & LEX_RESWDOK)
++		lex_rwlen = 0;
+ 	    }
+ 	}
+ 

Added: trunk/binutils/binutils-2.26-upstream_fix-2.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/binutils/binutils-2.26-upstream_fix-2.patch	Tue Feb 16 14:59:58 2016	(r3355)
@@ -0,0 +1,388 @@
+Submitted By: Bruce Dubbs <bdubbs at linuxfromscratch.org>
+Date: 2016-02-16
+Initial Package Version: 2.26
+Origin: Upstream
+Description: Various patches including some security issues
+
+--- a/bfd/elf32-i386.c	2016-01-25 09:51:06.000000000 +0100
++++ b/bfd/elf32-i386.c	2016-02-16 14:47:00.724974874 +0100
+@@ -4016,10 +4016,12 @@
+ 
+ 	  /* It is relative to .got.plt section.  */
+ 	  if (h->got.offset != (bfd_vma) -1)
+-	    /* Use GOT entry.  */
++	    /* Use GOT entry.  Mask off the least significant bit in
++	       GOT offset which may be set by R_386_GOT32 processing
++	       below.  */
+ 	    relocation = (htab->elf.sgot->output_section->vma
+ 			  + htab->elf.sgot->output_offset
+-			  + h->got.offset - offplt);
++			  + (h->got.offset & ~1) - offplt);
+ 	  else
+ 	    /* Use GOTPLT entry.  */
+ 	    relocation = (h->plt.offset / plt_entry_size - 1 + 3) * 4;
+--- a/bfd/elf64-x86-64.c	2016-01-25 09:51:06.000000000 +0100
++++ b/bfd/elf64-x86-64.c	2016-02-16 14:45:48.379450511 +0100
+@@ -3190,35 +3190,43 @@
+ 	}
+       else
+ 	{
+-	  asection *asect;
+-	  bfd_size_type size;
++	  bfd_signed_vma distance;
+ 
+ 	  /* At this point, we don't know the load addresses of TSEC
+ 	     section nor SEC section.  We estimate the distrance between
+-	     SEC and TSEC.  */
+-	  size = 0;
+-	  for (asect = sec->output_section;
+-	       asect != NULL && asect != tsec->output_section;
+-	       asect = asect->next)
++	     SEC and TSEC.  We store the estimated distances in the
++	     compressed_size field of the output section, which is only
++	     used to decompress the compressed input section.  */
++	  if (sec->output_section->compressed_size == 0)
+ 	    {
+-	      asection *i;
+-	      for (i = asect->output_section->map_head.s;
+-		   i != NULL;
+-		   i = i->map_head.s)
++	      asection *asect;
++	      bfd_size_type size = 0;
++	      for (asect = link_info->output_bfd->sections;
++		   asect != NULL;
++		   asect = asect->next)
+ 		{
+-		  size = align_power (size, i->alignment_power);
+-		  size += i->size;
++		  asection *i;
++		  for (i = asect->map_head.s;
++		       i != NULL;
++		       i = i->map_head.s)
++		    {
++		      size = align_power (size, i->alignment_power);
++		      size += i->size;
++		    }
++		  asect->compressed_size = size;
+ 		}
+ 	    }
+ 
+ 	  /* Don't convert GOTPCREL relocations if TSEC isn't placed
+ 	     after SEC.  */
+-	  if (asect == NULL)
++	  distance = (tsec->output_section->compressed_size
++		      - sec->output_section->compressed_size);
++	  if (distance < 0)
+ 	    continue;
+ 
+ 	  /* Take PT_GNU_RELRO segment into account by adding
+ 	     maxpagesize.  */
+-	  if ((toff + size + maxpagesize - roff + 0x80000000)
++	  if ((toff + distance + maxpagesize - roff + 0x80000000)
+ 	      > 0xffffffff)
+ 	    continue;
+ 	}
+--- a/gas/config/tc-i386.c	2016-01-25 09:51:06.000000000 +0100
++++ b/gas/config/tc-i386.c	2016-02-16 14:46:28.557300128 +0100
+@@ -552,6 +552,10 @@
+    specified explicitly.  */
+ static int omit_lock_prefix = 0;
+ 
++/* 1 if the assembler should generate relax relocations.  */
++static int generate_relax_relocations
++  = DEFAULT_GENERATE_X86_RELAX_RELOCATIONS;
++
+ static enum check_kind
+   {
+     check_none = 0,
+@@ -7241,9 +7245,14 @@
+ 	      /* Check for "call/jmp *mem", "mov mem, %reg",
+ 		 "test %reg, mem" and "binop mem, %reg" where binop
+ 		 is one of adc, add, and, cmp, or, sbb, sub, xor
+-		 instructions.  */
+-	      if ((i.rm.mode == 2
+-		   || (i.rm.mode == 0 && i.rm.regmem == 5))
++		 instructions.  Always generate R_386_GOT32X for
++		 "sym*GOT" operand in 32-bit mode.  */
++	      if ((generate_relax_relocations
++		   || (!object_64bit
++		       && i.rm.mode == 0
++		       && i.rm.regmem == 5))
++		  && (i.rm.mode == 2
++		      || (i.rm.mode == 0 && i.rm.regmem == 5))
+ 		  && ((i.operands == 1
+ 		       && i.tm.base_opcode == 0xff
+ 		       && (i.rm.reg == 2 || i.rm.reg == 4))
+@@ -9616,6 +9625,7 @@
+ #define OPTION_MSHARED (OPTION_MD_BASE + 21)
+ #define OPTION_MAMD64 (OPTION_MD_BASE + 22)
+ #define OPTION_MINTEL64 (OPTION_MD_BASE + 23)
++#define OPTION_MRELAX_RELOCATIONS (OPTION_MD_BASE + 24)
+ 
+ struct option md_longopts[] =
+ {
+@@ -9647,6 +9657,7 @@
+   {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ},
+ #endif
+   {"momit-lock-prefix", required_argument, NULL, OPTION_OMIT_LOCK_PREFIX},
++  {"mrelax-relocations", required_argument, NULL, OPTION_MRELAX_RELOCATIONS},
+   {"mevexrcig", required_argument, NULL, OPTION_MEVEXRCIG},
+   {"mamd64", no_argument, NULL, OPTION_MAMD64},
+   {"mintel64", no_argument, NULL, OPTION_MINTEL64},
+@@ -9966,6 +9977,15 @@
+         as_fatal (_("invalid -momit-lock-prefix= option: `%s'"), arg);
+       break;
+ 
++    case OPTION_MRELAX_RELOCATIONS:
++      if (strcasecmp (arg, "yes") == 0)
++        generate_relax_relocations = 1;
++      else if (strcasecmp (arg, "no") == 0)
++        generate_relax_relocations = 0;
++      else
++        as_fatal (_("invalid -mrelax-relocations= option: `%s'"), arg);
++      break;
++
+     case OPTION_MAMD64:
+       cpu_arch_flags.bitfield.cpuamd64 = 1;
+       cpu_arch_flags.bitfield.cpuintel64 = 0;
+@@ -10146,6 +10166,9 @@
+   -momit-lock-prefix=[no|yes]\n\
+                           strip all lock prefixes\n"));
+   fprintf (stream, _("\
++  -mrelax-relocations=[no|yes]\n\
++                          generate relax relocations\n"));
++  fprintf (stream, _("\
+   -mamd64                 accept only AMD64 ISA\n"));
+   fprintf (stream, _("\
+   -mintel64               accept only Intel64 ISA\n"));
+--- a/gas/config.in	2015-11-13 09:27:41.000000000 +0100
++++ b/gas/config.in	2016-02-16 14:46:28.556300107 +0100
+@@ -39,6 +39,9 @@
+ /* Define if you want compressed debug sections by default. */
+ #undef DEFAULT_FLAG_COMPRESS_DEBUG
+ 
++/* Define to 1 if you want to generate x86 relax relocations by default. */
++#undef DEFAULT_GENERATE_X86_RELAX_RELOCATIONS
++
+ /* Supported emulations. */
+ #undef EMULATIONS
+ 
+--- a/gas/configure	2016-01-25 09:54:08.000000000 +0100
++++ b/gas/configure	2016-02-16 14:46:28.560300191 +0100
+@@ -765,6 +765,7 @@
+ enable_targets
+ enable_checking
+ enable_compressed_debug_sections
++enable_x86_relax_relocations
+ enable_werror
+ enable_build_warnings
+ enable_nls
+@@ -1415,6 +1416,8 @@
+   --enable-checking       enable run-time checks
+   --enable-compressed-debug-sections={all,gas,none}
+                           compress debug sections by default]
++  --enable-x86-relax-relocations
++                          generate x86 relax relocations by default
+   --enable-werror         treat compile warnings as errors
+   --enable-build-warnings enable build-time compiler warnings
+   --disable-nls           do not use Native Language Support
+@@ -10972,7 +10975,7 @@
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 10975 "configure"
++#line 10978 "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -11078,7 +11081,7 @@
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 11081 "configure"
++#line 11084 "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -11680,6 +11683,17 @@
+ esac
+ fi
+ 
++# PR gas/19520
++# Decide if x86 assembler should generate relax relocations.
++ac_default_x86_relax_relocations=unset
++# Provide a configure time option to override our default.
++# Check whether --enable-x86_relax_relocations was given.
++if test "${enable_x86_relax_relocations+set}" = set; then :
++  enableval=$enable_x86_relax_relocations; case "${enableval}" in
++  no)  ac_default_x86_relax_relocations=0 ;;
++esac
++fi
++
+ using_cgen=no
+ 
+ 
+@@ -12085,6 +12099,17 @@
+ 
+ 	;;
+ 
++      i386-*-solaris2 \
++      | x86_64-*-solaris2 \
++      | i386-*-solaris2.[0-9] \
++      | i386-*-solaris2.1[01] \
++      | x86_64-*-solaris2.1[01])
++	if test ${this_target} = $target \
++	   && test ${ac_default_x86_relax_relocations} = unset; then
++	  ac_default_x86_relax_relocations=0
++	fi
++	;;
++
+       i860-*-*)
+ 	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GAS support for ${generic_target} is preliminary and a work in progress" >&5
+ $as_echo "$as_me: WARNING: GAS support for ${generic_target} is preliminary and a work in progress" >&2;}
+@@ -12505,7 +12530,16 @@
+ 
+ done
+ 
+-if test x$ac_default_compressed_debug_sections == xyes ; then
++if test ${ac_default_x86_relax_relocations} = unset; then
++  ac_default_x86_relax_relocations=1
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define DEFAULT_GENERATE_X86_RELAX_RELOCATIONS $ac_default_x86_relax_relocations
++_ACEOF
++
++
++if test x$ac_default_compressed_debug_sections = xyes ; then
+ 
+ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h
+ 
+--- a/gas/configure.ac	2016-01-25 09:51:06.000000000 +0100
++++ b/gas/configure.ac	2016-02-16 14:46:28.560300191 +0100
+@@ -77,6 +77,17 @@
+   *)   ac_default_compressed_debug_sections=unset ;;
+ esac])dnl
+ 
++# PR gas/19520
++# Decide if x86 assembler should generate relax relocations.
++ac_default_x86_relax_relocations=unset
++# Provide a configure time option to override our default.
++AC_ARG_ENABLE(x86_relax_relocations,
++	      AS_HELP_STRING([--enable-x86-relax-relocations],
++	      [generate x86 relax relocations by default]),
++[case "${enableval}" in
++  no)  ac_default_x86_relax_relocations=0 ;;
++esac])dnl
++
+ using_cgen=no
+ 
+ AM_BINUTILS_WARNINGS
+@@ -168,6 +179,17 @@
+ 	AC_DEFINE(STRICTCOFF, 1, [Using strict COFF?])
+ 	;;
+ 
++      i386-*-solaris2 \
++      | x86_64-*-solaris2 \
++      | i386-*-solaris2.[[0-9]] \
++      | i386-*-solaris2.1[[01]] \
++      | x86_64-*-solaris2.1[[01]])
++	if test ${this_target} = $target \
++	   && test ${ac_default_x86_relax_relocations} = unset; then
++	  ac_default_x86_relax_relocations=0
++	fi
++	;;
++
+       i860-*-*)
+ 	AC_MSG_WARN(GAS support for ${generic_target} is preliminary and a work in progress)
+ 	;;
+@@ -549,7 +571,14 @@
+ 
+ done
+ 
+-if test x$ac_default_compressed_debug_sections == xyes ; then
++if test ${ac_default_x86_relax_relocations} = unset; then
++  ac_default_x86_relax_relocations=1
++fi
++AC_DEFINE_UNQUOTED(DEFAULT_GENERATE_X86_RELAX_RELOCATIONS,
++  $ac_default_x86_relax_relocations,
++  [Define to 1 if you want to generate x86 relax relocations by default.])
++
++if test x$ac_default_compressed_debug_sections = xyes ; then
+   AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.])
+ fi
+ 
+--- a/ld/configure	2016-01-25 09:54:11.000000000 +0100
++++ b/ld/configure	2016-02-16 14:43:18.377200561 +0100
+@@ -17134,7 +17134,7 @@
+   fi
+ done
+ 
+-if test x$ac_default_compressed_debug_sections == xyes ; then
++if test x$ac_default_compressed_debug_sections = xyes ; then
+ 
+ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h
+ 
+--- a/ld/configure.ac	2015-11-13 09:27:42.000000000 +0100
++++ b/ld/configure.ac	2016-02-16 14:43:18.377200561 +0100
+@@ -384,7 +384,7 @@
+   fi
+ done
+ 
+-if test x$ac_default_compressed_debug_sections == xyes ; then
++if test x$ac_default_compressed_debug_sections = xyes ; then
+   AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.])
+ fi
+ 
+--- a/ld/lexsup.c	2015-11-13 09:27:42.000000000 +0100
++++ b/ld/lexsup.c	2016-02-16 14:47:32.165629964 +0100
+@@ -1586,15 +1586,14 @@
+   /* We may have -Bsymbolic, -Bsymbolic-functions, --dynamic-list-data,
+      --dynamic-list-cpp-new, --dynamic-list-cpp-typeinfo and
+      --dynamic-list FILE.  -Bsymbolic and -Bsymbolic-functions are
+-     for shared libraries.  -Bsymbolic overrides all others and vice
+-     versa.  */
++     for PIC outputs.  -Bsymbolic overrides all others and vice versa.  */
+   switch (command_line.symbolic)
+     {
+     case symbolic_unset:
+       break;
+     case symbolic:
+-      /* -Bsymbolic is for shared library only.  */
+-      if (bfd_link_dll (&link_info))
++      /* -Bsymbolic is for PIC output only.  */
++      if (bfd_link_pic (&link_info))
+ 	{
+ 	  link_info.symbolic = TRUE;
+ 	  /* Should we free the unused memory?  */
+@@ -1603,8 +1602,8 @@
+ 	}
+       break;
+     case symbolic_functions:
+-      /* -Bsymbolic-functions is for shared library only.  */
+-      if (bfd_link_dll (&link_info))
++      /* -Bsymbolic-functions is for PIC output only.  */
++      if (bfd_link_pic (&link_info))
+ 	command_line.dynamic_list = dynamic_list_data;
+       break;
+     }
+--- a/opcodes/i386-dis.c	2016-01-25 09:51:06.000000000 +0100
++++ b/opcodes/i386-dis.c	2016-02-16 14:48:03.213272848 +0100
+@@ -13644,7 +13644,7 @@
+     if (op_index[i] != -1 && op_riprel[i])
+       {
+ 	(*info->fprintf_func) (info->stream, "        # ");
+-	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
++	(*info->print_address_func) ((bfd_vma) (start_pc + (codep - start_codep)
+ 						+ op_address[op_index[i]]), info);
+ 	break;
+       }
+@@ -16158,7 +16158,7 @@
+ 	     the displacement is added!  */
+ 	  mask = 0xffff;
+ 	  if ((prefixes & PREFIX_DATA) == 0)
+-	    segment = ((start_pc + codep - start_codep)
++	    segment = ((start_pc + (codep - start_codep))
+ 		       & ~((bfd_vma) 0xffff));
+ 	}
+       if (address_mode != mode_64bit

Added: trunk/gcc/gcc-5.3.0-upstream_fixes-1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/gcc/gcc-5.3.0-upstream_fixes-1.patch	Tue Feb 16 14:59:58 2016	(r3355)
@@ -0,0 +1,7640 @@
+Submitted By:            Bruce Dubbs <bdubbs at liinuxfromscratch.org>
+Date:                    2016-02-16
+Initial Package Version: 5.3.0
+Upstream Status:         Committed
+Origin:                  Upstream
+Description:             Fix various issues identified upstream.
+
+--- a/gcc/alias.c	2015-11-18 13:23:14.000000000 +0100
++++ b/gcc/alias.c	2016-02-16 15:42:07.862357854 +0100
+@@ -1880,7 +1880,7 @@
+ }
+ 
+ /* Return TRUE if EXPR refers to a VALUE whose uid is greater than
+-   that of V.  */
++   (or equal to) that of V.  */
+ 
+ static bool
+ refs_newer_value_p (const_rtx expr, rtx v)
+@@ -1888,14 +1888,14 @@
+   int minuid = CSELIB_VAL_PTR (v)->uid;
+   subrtx_iterator::array_type array;
+   FOR_EACH_SUBRTX (iter, array, expr, NONCONST)
+-    if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid > minuid)
++    if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid >= minuid)
+       return true;
+   return false;
+ }
+ 
+ /* Convert the address X into something we can use.  This is done by returning
+-   it unchanged unless it is a value; in the latter case we call cselib to get
+-   a more useful rtx.  */
++   it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE
++   we call cselib to get a more useful rtx.  */
+ 
+ rtx
+ get_addr (rtx x)
+@@ -1904,7 +1904,23 @@
+   struct elt_loc_list *l;
+ 
+   if (GET_CODE (x) != VALUE)
+-    return x;
++    {
++      if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
++	  && GET_CODE (XEXP (x, 0)) == VALUE
++	  && CONST_SCALAR_INT_P (XEXP (x, 1)))
++	{
++	  rtx op0 = get_addr (XEXP (x, 0));
++	  if (op0 != XEXP (x, 0))
++	    {
++	      if (GET_CODE (x) == PLUS
++		  && GET_CODE (XEXP (x, 1)) == CONST_INT)
++		return plus_constant (GET_MODE (x), op0, INTVAL (XEXP (x, 1)));
++	      return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
++					  op0, XEXP (x, 1));
++	    }
++	}
++      return x;
++    }
+   v = CSELIB_VAL_PTR (x);
+   if (v)
+     {
+--- a/gcc/builtins.c	2015-10-08 18:54:23.000000000 +0200
++++ b/gcc/builtins.c	2016-02-16 15:12:17.980963965 +0100
+@@ -497,6 +497,10 @@
+ 	{
+ 	  *bitposp = ptr_misalign * BITS_PER_UNIT;
+ 	  *alignp = ptr_align * BITS_PER_UNIT;
++	  /* Make sure to return a sensible alignment when the multiplication
++	     by BITS_PER_UNIT overflowed.  */
++	  if (*alignp == 0)
++	    *alignp = 1u << (HOST_BITS_PER_INT - 1);
+ 	  /* We cannot really tell whether this result is an approximation.  */
+ 	  return true;
+ 	}
+--- a/gcc/c/c-decl.c	2015-09-09 09:30:42.000000000 +0200
++++ b/gcc/c/c-decl.c	2016-02-16 15:42:15.294482080 +0100
+@@ -5366,6 +5366,8 @@
+   tree returned_attrs = NULL_TREE;
+   bool bitfield = width != NULL;
+   tree element_type;
++  tree orig_qual_type = NULL;
++  size_t orig_qual_indirect = 0;
+   struct c_arg_info *arg_info = 0;
+   addr_space_t as1, as2, address_space;
+   location_t loc = UNKNOWN_LOCATION;
+@@ -5404,9 +5406,9 @@
+ 	case cdk_function:
+ 	case cdk_pointer:
+ 	  funcdef_syntax = (decl->kind == cdk_function);
+-	  decl = decl->declarator;
+ 	  if (first_non_attr_kind == cdk_attrs)
+ 	    first_non_attr_kind = decl->kind;
++	  decl = decl->declarator;
+ 	  break;
+ 
+ 	case cdk_attrs:
+@@ -5528,12 +5530,17 @@
+   if ((TREE_CODE (type) == ARRAY_TYPE
+        || first_non_attr_kind == cdk_array)
+       && TYPE_QUALS (element_type))
+-    type = TYPE_MAIN_VARIANT (type);
++    {
++      orig_qual_type = type;
++      type = TYPE_MAIN_VARIANT (type);
++    }
+   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+ 		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
+ 		| (volatilep ? TYPE_QUAL_VOLATILE : 0)
+ 		| (atomicp ? TYPE_QUAL_ATOMIC : 0)
+ 		| ENCODE_QUAL_ADDR_SPACE (address_space));
++  if (type_quals != TYPE_QUALS (element_type))
++    orig_qual_type = NULL_TREE;
+ 
+   /* Applying the _Atomic qualifier to an array type (through the use
+      of typedefs or typeof) must be detected here.  If the qualifier
+@@ -6024,6 +6031,7 @@
+ 		array_ptr_attrs = NULL_TREE;
+ 		array_parm_static = 0;
+ 	      }
++	    orig_qual_indirect++;
+ 	    break;
+ 	  }
+ 	case cdk_function:
+@@ -6033,6 +6041,7 @@
+ 	       attributes.  */
+ 	    bool really_funcdef = false;
+ 	    tree arg_types;
++	    orig_qual_type = NULL_TREE;
+ 	    if (funcdef_flag)
+ 	      {
+ 		const struct c_declarator *t = declarator->declarator;
+@@ -6133,7 +6142,9 @@
+ 	      pedwarn (loc, OPT_Wpedantic,
+ 		       "ISO C forbids qualified function types");
+ 	    if (type_quals)
+-	      type = c_build_qualified_type (type, type_quals);
++	      type = c_build_qualified_type (type, type_quals, orig_qual_type,
++					     orig_qual_indirect);
++	    orig_qual_type = NULL_TREE;
+ 	    size_varies = false;
+ 
+ 	    /* When the pointed-to type involves components of variable size,
+@@ -6331,7 +6342,8 @@
+ 	pedwarn (loc, OPT_Wpedantic,
+ 		 "ISO C forbids qualified function types");
+       if (type_quals)
+-	type = c_build_qualified_type (type, type_quals);
++	type = c_build_qualified_type (type, type_quals, orig_qual_type,
++				       orig_qual_indirect);
+       decl = build_decl (declarator->id_loc,
+ 			 TYPE_DECL, declarator->u.id, type);
+       if (declspecs->explicit_signed_p)
+@@ -6384,7 +6396,8 @@
+ 	pedwarn (loc, OPT_Wpedantic,
+ 		 "ISO C forbids const or volatile function types");
+       if (type_quals)
+-	type = c_build_qualified_type (type, type_quals);
++	type = c_build_qualified_type (type, type_quals, orig_qual_type,
++				       orig_qual_indirect);
+       return type;
+     }
+ 
+@@ -6431,8 +6444,16 @@
+ 	  {
+ 	    /* Transfer const-ness of array into that of type pointed to.  */
+ 	    type = TREE_TYPE (type);
++	    if (orig_qual_type != NULL_TREE)
++	      {
++		if (orig_qual_indirect == 0)
++		  orig_qual_type = TREE_TYPE (orig_qual_type);
++		else
++		  orig_qual_indirect--;
++	      }
+ 	    if (type_quals)
+-	      type = c_build_qualified_type (type, type_quals);
++	      type = c_build_qualified_type (type, type_quals, orig_qual_type,
++					     orig_qual_indirect);
+ 	    type = c_build_pointer_type (type);
+ 	    type_quals = array_ptr_quals;
+ 	    if (type_quals)
+@@ -6523,7 +6544,8 @@
+ 	    TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
+ 						   NULL_TREE);
+ 	  }
+-	type = c_build_qualified_type (type, type_quals);
++	type = c_build_qualified_type (type, type_quals, orig_qual_type,
++				       orig_qual_indirect);
+ 	decl = build_decl (declarator->id_loc,
+ 			   FIELD_DECL, declarator->u.id, type);
+ 	DECL_NONADDRESSABLE_P (decl) = bitfield;
+@@ -6635,7 +6657,8 @@
+ 	/* An uninitialized decl with `extern' is a reference.  */
+ 	int extern_ref = !initialized && storage_class == csc_extern;
+ 
+-	type = c_build_qualified_type (type, type_quals);
++	type = c_build_qualified_type (type, type_quals, orig_qual_type,
++				       orig_qual_indirect);
+ 
+ 	/* C99 6.2.2p7: It is invalid (compile-time undefined
+ 	   behavior) to create an 'extern' declaration for a
+@@ -7996,7 +8019,22 @@
+   precision = MAX (tree_int_cst_min_precision (minnode, sign),
+ 		   tree_int_cst_min_precision (maxnode, sign));
+ 
+-  if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
++  /* If the precision of the type was specified with an attribute and it
++     was too small, give an error.  Otherwise, use it.  */
++  if (TYPE_PRECISION (enumtype))
++    {
++      if (precision > TYPE_PRECISION (enumtype))
++	{
++	  TYPE_PRECISION (enumtype) = 0;
++	  error ("specified mode too small for enumeral values");
++	}
++      else
++	precision = TYPE_PRECISION (enumtype);
++    }
++
++  if (TYPE_PACKED (enumtype)
++      || precision > TYPE_PRECISION (integer_type_node)
++      || TYPE_PRECISION (enumtype))
+     {
+       tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
+       if (tem == NULL)
+@@ -8012,16 +8050,7 @@
+   TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
+   TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
+   TYPE_SIZE (enumtype) = 0;
+-
+-  /* If the precision of the type was specific with an attribute and it
+-     was too small, give an error.  Otherwise, use it.  */
+-  if (TYPE_PRECISION (enumtype))
+-    {
+-      if (precision > TYPE_PRECISION (enumtype))
+-	error ("specified mode too small for enumeral values");
+-    }
+-  else
+-    TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
++  TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
+ 
+   layout_type (enumtype);
+ 
+--- a/gcc/c/c-typeck.c	2015-10-05 14:35:20.000000000 +0200
++++ b/gcc/c/c-typeck.c	2016-02-16 15:33:24.580979081 +0100
+@@ -10754,6 +10754,20 @@
+               return error_mark_node;
+             }
+ 
++	  /* It's not precisely specified how the usual arithmetic
++	     conversions apply to the vector types.  Here, we use
++	     the unsigned type if one of the operands is signed and
++	     the other one is unsigned.  */
++	  if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
++	    {
++	      if (!TYPE_UNSIGNED (type0))
++		op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
++	      else
++		op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
++	      warning_at (location, OPT_Wsign_compare, "comparison between "
++			  "types %qT and %qT", type0, type1);
++	    }
++
+           /* Always construct signed integer vector type.  */
+           intt = c_common_type_for_size (GET_MODE_BITSIZE
+ 					   (TYPE_MODE (TREE_TYPE (type0))), 0);
+@@ -10896,6 +10910,20 @@
+               return error_mark_node;
+             }
+ 
++	  /* It's not precisely specified how the usual arithmetic
++	     conversions apply to the vector types.  Here, we use
++	     the unsigned type if one of the operands is signed and
++	     the other one is unsigned.  */
++	  if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
++	    {
++	      if (!TYPE_UNSIGNED (type0))
++		op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
++	      else
++		op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
++	      warning_at (location, OPT_Wsign_compare, "comparison between "
++			  "types %qT and %qT", type0, type1);
++	    }
++
+           /* Always construct signed integer vector type.  */
+           intt = c_common_type_for_size (GET_MODE_BITSIZE
+ 					   (TYPE_MODE (TREE_TYPE (type0))), 0);
+@@ -12578,10 +12606,15 @@
+ }
+ 
+ /* Make a variant type in the proper way for C/C++, propagating qualifiers
+-   down to the element type of an array.  */
++   down to the element type of an array.  If ORIG_QUAL_TYPE is not
++   NULL, then it should be used as the qualified type
++   ORIG_QUAL_INDIRECT levels down in array type derivation (to
++   preserve information about the typedef name from which an array
++   type was derived).  */
+ 
+ tree
+-c_build_qualified_type (tree type, int type_quals)
++c_build_qualified_type (tree type, int type_quals, tree orig_qual_type,
++			size_t orig_qual_indirect)
+ {
+   if (type == error_mark_node)
+     return type;
+@@ -12590,18 +12623,22 @@
+     {
+       tree t;
+       tree element_type = c_build_qualified_type (TREE_TYPE (type),
+-						  type_quals);
++						  type_quals, orig_qual_type,
++						  orig_qual_indirect - 1);
+ 
+       /* See if we already have an identically qualified type.  */
+-      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+-	{
+-	  if (TYPE_QUALS (strip_array_types (t)) == type_quals
+-	      && TYPE_NAME (t) == TYPE_NAME (type)
+-	      && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+-	      && attribute_list_equal (TYPE_ATTRIBUTES (t),
+-				       TYPE_ATTRIBUTES (type)))
+-	    break;
+-	}
++      if (orig_qual_type && orig_qual_indirect == 0)
++	t = orig_qual_type;
++      else
++	for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
++	  {
++	    if (TYPE_QUALS (strip_array_types (t)) == type_quals
++		&& TYPE_NAME (t) == TYPE_NAME (type)
++		&& TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
++		&& attribute_list_equal (TYPE_ATTRIBUTES (t),
++					 TYPE_ATTRIBUTES (type)))
++	      break;
++	  }
+       if (!t)
+ 	{
+           tree domain = TYPE_DOMAIN (type);
+@@ -12639,7 +12676,10 @@
+       type_quals &= ~TYPE_QUAL_RESTRICT;
+     }
+ 
+-  return build_qualified_type (type, type_quals);
++  tree var_type = (orig_qual_type && orig_qual_indirect == 0
++		   ? orig_qual_type
++		   : build_qualified_type (type, type_quals));
++  return var_type;
+ }
+ 
+ /* Build a VA_ARG_EXPR for the C parser.  */
+--- a/gcc/calls.c	2015-11-26 12:36:40.000000000 +0100
++++ b/gcc/calls.c	2016-02-16 15:03:58.694956366 +0100
+@@ -576,12 +576,9 @@
+       /* We assume that alloca will always be called by name.  It
+ 	 makes no sense to pass it as a pointer-to-function to
+ 	 anything that does not understand its behavior.  */
+-      if (((IDENTIFIER_LENGTH (name_decl) == 6
+-	    && name[0] == 'a'
+-	    && ! strcmp (name, "alloca"))
+-	   || (IDENTIFIER_LENGTH (name_decl) == 16
+-	       && name[0] == '_'
+-	       && ! strcmp (name, "__builtin_alloca"))))
++      if (IDENTIFIER_LENGTH (name_decl) == 6
++	  && name[0] == 'a'
++	  && ! strcmp (name, "alloca"))
+ 	flags |= ECF_MAY_BE_ALLOCA;
+ 
+       /* Disregard prefix _, __, __x or __builtin_.  */
+@@ -627,6 +624,17 @@
+ 	flags |= ECF_NORETURN;
+     }
+ 
++  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
++    switch (DECL_FUNCTION_CODE (fndecl))
++      {
++      case BUILT_IN_ALLOCA:
++      case BUILT_IN_ALLOCA_WITH_ALIGN:
++	flags |= ECF_MAY_BE_ALLOCA;
++	break;
++      default:
++	break;
++      }
++
+   return flags;
+ }
+ 
+--- a/gcc/c-family/c-common.h	2015-04-10 09:54:46.000000000 +0200
++++ b/gcc/c-family/c-common.h	2016-02-16 15:13:32.726521859 +0100
+@@ -850,7 +850,7 @@
+ 			     bool = true);
+ 
+ /* Add qualifiers to a type, in the fashion for C.  */
+-extern tree c_build_qualified_type (tree, int);
++extern tree c_build_qualified_type (tree, int, tree = NULL_TREE, size_t = 0);
+ 
+ /* Build tree nodes and builtin functions common to both C and C++ language
+    frontends.  */
+--- a/gcc/c-family/c-ppoutput.c	2015-01-09 21:18:42.000000000 +0100
++++ b/gcc/c-family/c-ppoutput.c	2016-02-16 15:41:59.150212479 +0100
+@@ -43,11 +43,11 @@
+   const cpp_token *prev;	/* Previous token.  */
+   const cpp_token *source;	/* Source token for spacing.  */
+   int src_line;			/* Line number currently being written.  */
+-  unsigned char printed;	/* Nonzero if something output at line.  */
++  bool printed;			/* True if something output at line.  */
+   bool first_time;		/* pp_file_change hasn't been called yet.  */
+-  const char *src_file;		/* Current source file.  */
+   bool prev_was_system_token;	/* True if the previous token was a
+ 				   system token.*/
++  const char *src_file;		/* Current source file.  */
+ } print;
+ 
+ /* Defined and undefined macros being queued for output with -dU at
+@@ -165,7 +165,7 @@
+ 
+   /* Initialize the print structure.  */
+   print.src_line = 1;
+-  print.printed = 0;
++  print.printed = false;
+   print.prev = 0;
+   print.outf = out_stream;
+   print.first_time = 1;
+@@ -218,12 +218,16 @@
+ 	    {
+ 	      line_marker_emitted = do_line_change (pfile, token, loc, false);
+ 	      putc (' ', print.outf);
++	      print.printed = true;
+ 	    }
+ 	  else if (print.source->flags & PREV_WHITE
+ 		   || (print.prev
+ 		       && cpp_avoid_paste (pfile, print.prev, token))
+ 		   || (print.prev == NULL && token->type == CPP_HASH))
+-	    putc (' ', print.outf);
++	    {
++	      putc (' ', print.outf);
++	      print.printed = true;
++	    }
+ 	}
+       else if (token->flags & PREV_WHITE)
+ 	{
+@@ -234,6 +238,7 @@
+ 	      && !in_pragma)
+ 	    line_marker_emitted = do_line_change (pfile, token, loc, false);
+ 	  putc (' ', print.outf);
++	  print.printed = true;
+ 	}
+ 
+       avoid_paste = false;
+@@ -251,7 +256,7 @@
+ 	    fprintf (print.outf, "%s %s", space, name);
+ 	  else
+ 	    fprintf (print.outf, "%s", name);
+-	  print.printed = 1;
++	  print.printed = true;
+ 	  in_pragma = true;
+ 	}
+       else if (token->type == CPP_PRAGMA_EOL)
+@@ -262,23 +267,23 @@
+       else
+ 	{
+ 	  if (cpp_get_options (parse_in)->debug)
+-	      linemap_dump_location (line_table, token->src_loc,
+-				     print.outf);
++	    linemap_dump_location (line_table, token->src_loc, print.outf);
+ 
+ 	  if (do_line_adjustments
+ 	      && !in_pragma
+ 	      && !line_marker_emitted
+-	      && print.prev_was_system_token != !!in_system_header_at(loc)
++	      && print.prev_was_system_token != !!in_system_header_at (loc)
+ 	      && !is_location_from_builtin_token (loc))
+ 	    /* The system-ness of this token is different from the one
+ 	       of the previous token.  Let's emit a line change to
+ 	       mark the new system-ness before we emit the token.  */
+ 	    {
+ 	      do_line_change (pfile, token, loc, false);
+-	      print.prev_was_system_token = !!in_system_header_at(loc);
++	      print.prev_was_system_token = !!in_system_header_at (loc);
+ 	    }
+ 	  cpp_output_token (token, print.outf);
+ 	  line_marker_emitted = false;
++	  print.printed = true;
+ 	}
+ 
+       /* CPP_COMMENT tokens and raw-string literal tokens can
+@@ -328,7 +333,7 @@
+       size_t len = pfile->out.cur - pfile->out.base;
+       maybe_print_line (pfile->out.first_line);
+       fwrite (pfile->out.base, 1, len, print.outf);
+-      print.printed = 1;
++      print.printed = true;
+       if (!CPP_OPTION (pfile, discard_comments))
+ 	account_for_newlines (pfile->out.base, len);
+     }
+@@ -351,7 +356,7 @@
+     {
+       putc ('\n', stream);
+       print.src_line++;
+-      print.printed = 0;
++      print.printed = false;
+     }
+ 
+   if (!flag_no_line_commands
+@@ -397,7 +402,7 @@
+   /* End any previous line of text.  */
+   if (print.printed)
+     putc ('\n', stream);
+-  print.printed = 0;
++  print.printed = false;
+ 
+   if (!flag_no_line_commands)
+     {
+@@ -472,7 +477,7 @@
+   if (!CPP_OPTION (pfile, traditional))
+     {
+       int spaces = LOCATION_COLUMN (src_loc) - 2;
+-      print.printed = 1;
++      print.printed = true;
+ 
+       while (-- spaces >= 0)
+ 	putc (' ', print.outf);
+@@ -515,6 +520,7 @@
+     fputs ((const char *) NODE_NAME (node), print.outf);
+ 
+   putc ('\n', print.outf);
++  print.printed = false;
+   linemap_resolve_location (line_table, line,
+ 			    LRK_MACRO_DEFINITION_LOCATION,
+ 			    &map);
+@@ -566,7 +572,7 @@
+     {
+       putc ('\n', print.outf);
+       print.src_line++;
+-      print.printed = 0;
++      print.printed = false;
+     }
+ 
+   for (q = define_queue; q;)
+@@ -575,6 +581,7 @@
+       fputs ("#define ", print.outf);
+       fputs (q->macro, print.outf);
+       putc ('\n', print.outf);
++      print.printed = false;
+       print.src_line++;
+       oq = q;
+       q = q->next;
+@@ -618,6 +625,7 @@
+     }
+ 
+   putc ('\n', print.outf);
++  print.printed = false;
+   print.src_line++;
+ }
+ 
+@@ -683,6 +691,7 @@
+   maybe_print_line (line);
+   fputs ("#pragma ", print.outf);
+   cpp_output_line (pfile, print.outf);
++  print.printed = false;
+   print.src_line++;
+ }
+ 
+@@ -696,6 +705,7 @@
+       fputs ((const char *) cpp_macro_definition (pfile, node),
+ 	     print.outf);
+       putc ('\n', print.outf);
++      print.printed = false;
+       print.src_line++;
+     }
+ 
+--- a/gcc/cfgexpand.c	2015-07-23 12:39:26.000000000 +0200
++++ b/gcc/cfgexpand.c	2016-02-16 15:06:16.880571076 +0100
+@@ -3367,6 +3367,12 @@
+ 	  {
+ 	    tree result = DECL_RESULT (current_function_decl);
+ 
++	    /* Mark we have return statement with missing bounds.  */
++	    if (!bnd
++		&& chkp_function_instrumented_p (cfun->decl)
++		&& !DECL_P (op0))
++	      bnd = error_mark_node;
++
+ 	    /* If we are not returning the current function's RESULT_DECL,
+ 	       build an assignment to it.  */
+ 	    if (op0 != result)
+@@ -3383,9 +3389,6 @@
+ 		op0 = build2 (MODIFY_EXPR, TREE_TYPE (result),
+ 			      result, op0);
+ 	      }
+-	    /* Mark we have return statement with missing bounds.  */
+-	    if (!bnd && chkp_function_instrumented_p (cfun->decl))
+-	      bnd = error_mark_node;
+ 	  }
+ 
+ 	if (!op0)
+--- a/gcc/cgraph.c	2015-06-17 09:42:39.000000000 +0200
++++ b/gcc/cgraph.c	2016-02-16 15:20:15.734660357 +0100
+@@ -2609,7 +2609,8 @@
+ 
+   if (avail > AVAIL_INTERPOSABLE)
+     for (cs = node->callers; cs != NULL; cs = cs->next_caller)
+-      if (!cs->indirect_inlining_edge)
++      if (!cs->indirect_inlining_edge
++	  && !cs->caller->thunk.thunk_p)
+         redirect_callers->safe_push (cs);
+   return false;
+ }
+--- a/gcc/cgraphclones.c	2015-04-02 07:14:26.000000000 +0200
++++ b/gcc/cgraphclones.c	2016-02-16 15:23:15.365194538 +0100
+@@ -367,6 +367,7 @@
+   new_thunk = cgraph_node::create (new_decl);
+   set_new_clone_decl_and_node_flags (new_thunk);
+   new_thunk->definition = true;
++  new_thunk->local.can_change_signature = node->local.can_change_signature;
+   new_thunk->thunk = thunk->thunk;
+   new_thunk->unique_name = in_lto_p;
+   new_thunk->former_clone_of = thunk->decl;
+--- a/gcc/cgraph.h	2015-04-01 09:41:17.000000000 +0200
++++ b/gcc/cgraph.h	2016-02-16 15:20:15.735660377 +0100
+@@ -1028,7 +1028,7 @@
+   cgraph_edge *get_edge (gimple call_stmt);
+ 
+   /* Collect all callers of cgraph_node and its aliases that are known to lead
+-     to NODE (i.e. are not overwritable).  */
++     to NODE (i.e. are not overwritable) and that are not thunks.  */
+   vec<cgraph_edge *> collect_callers (void);
+ 
+   /* Remove all callers from the node.  */
+--- a/gcc/cgraphunit.c	2015-11-16 16:01:01.000000000 +0100
++++ b/gcc/cgraphunit.c	2016-02-16 15:12:32.756273515 +0100
+@@ -585,6 +585,7 @@
+       cgraph_node *t = cgraph_node::get (thunk.alias);
+ 
+       create_edge (t, NULL, 0, CGRAPH_FREQ_BASE);
++      callees->can_throw_external = !TREE_NOTHROW (t->decl);
+       /* Target code in expand_thunk may need the thunk's target
+ 	 to be analyzed, so recurse here.  */
+       if (!t->analyzed)
+--- a/gcc/combine.c	2015-11-02 22:04:33.000000000 +0100
++++ b/gcc/combine.c	2016-02-16 15:44:42.280974494 +0100
+@@ -7227,6 +7227,10 @@
+       if (len >= HOST_BITS_PER_WIDE_INT)
+ 	break;
+ 
++      /* Don't try to compute in too wide unsupported modes.  */
++      if (!targetm.scalar_mode_supported_p (compute_mode))
++	break;
++
+       /* Now compute the equivalent expression.  Make a copy of INNER
+ 	 for the SET_DEST in case it is a MEM into which we will substitute;
+ 	 we don't want shared RTL in that case.  */
+@@ -13781,10 +13785,10 @@
+ 		break;
+ 	      tem_insn = i3;
+ 	      /* If the new I2 sets the same register that is marked dead
+-		 in the note, the note now should not be put on I2, as the
+-		 note refers to a previous incarnation of the reg.  */
++		 in the note, we do not know where to put the note.
++		 Give up.  */
+ 	      if (i2 != 0 && reg_set_p (XEXP (note, 0), PATTERN (i2)))
+-		tem_insn = i2;
++		break;
+ 	    }
+ 
+ 	  if (place == 0)
+--- a/gcc/common.opt	2015-07-01 19:06:52.000000000 +0200
++++ b/gcc/common.opt	2016-02-16 15:22:53.030757235 +0100
+@@ -1845,7 +1845,7 @@
+ 
+ frandom-seed=
+ Common Joined RejectNegative Var(common_deferred_options) Defer
+--frandom-seed=<number>	Make compile reproducible using <number>
++-frandom-seed=<string>	Make compile reproducible using <string>
+ 
+ ; This switch causes the command line that was used to create an
+ ; object file to be recorded into the object file.  The exact format
+--- a/gcc/config/i386/constraints.md	2015-01-05 13:33:28.000000000 +0100
++++ b/gcc/config/i386/constraints.md	2016-02-16 15:34:07.740807135 +0100
+@@ -149,6 +149,7 @@
+ ;;  s  Sibcall memory operand, not valid for TARGET_X32
+ ;;  w  Call memory operand, not valid for TARGET_X32
+ ;;  z  Constant call address operand.
++;;  C  SSE constant operand.
+ 
+ (define_constraint "Bs"
+   "@internal Sibcall memory operand."
+@@ -164,6 +165,10 @@
+   "@internal Constant call address operand."
+   (match_operand 0 "constant_call_address_operand"))
+ 
++(define_constraint "BC"
++  "@internal SSE constant operand."
++  (match_test "standard_sse_constant_p (op)"))
++
+ ;; Integer constant constraints.
+ (define_constraint "I"
+   "Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
+@@ -214,8 +219,8 @@
+ 
+ ;; This can theoretically be any mode's CONST0_RTX.
+ (define_constraint "C"
+-  "Standard SSE floating point constant."
+-  (match_test "standard_sse_constant_p (op)"))
++  "SSE constant zero operand."
++  (match_test "standard_sse_constant_p (op) == 1"))
+ 
+ ;; Constant-or-symbol-reference constraints.
+ 
+--- a/gcc/config/i386/i386.c	2015-11-18 16:45:26.000000000 +0100
++++ b/gcc/config/i386/i386.c	2016-02-16 15:42:11.482418338 +0100
+@@ -115,6 +115,7 @@
+ #include "tree-iterator.h"
+ #include "tree-chkp.h"
+ #include "rtl-chkp.h"
++#include "dojump.h"
+ 
+ static rtx legitimize_dllimport_symbol (rtx, bool);
+ static rtx legitimize_pe_coff_extern_decl (rtx, bool);
+@@ -562,17 +563,17 @@
+   {4, 6, 6},				/* cost of storing fp registers
+ 					   in SFmode, DFmode and XFmode */
+ 
+-  1,					/* cost of moving MMX register */
+-  {1, 1},				/* cost of loading MMX registers
++  2,					/* cost of moving MMX register */
++  {2, 2},				/* cost of loading MMX registers
+ 					   in SImode and DImode */
+-  {1, 1},				/* cost of storing MMX registers
++  {2, 2},				/* cost of storing MMX registers
+ 					   in SImode and DImode */
+-  1,					/* cost of moving SSE register */
+-  {1, 1, 1},				/* cost of loading SSE registers
++  2,					/* cost of moving SSE register */
++  {2, 2, 8},				/* cost of loading SSE registers
+ 					   in SImode, DImode and TImode */
+-  {1, 1, 1},				/* cost of storing SSE registers
++  {2, 2, 8},				/* cost of storing SSE registers
+ 					   in SImode, DImode and TImode */
+-  1,					/* MMX or SSE register to integer */
++  3,					/* MMX or SSE register to integer */
+   64,					/* size of l1 cache.  */
+   128,					/* size of l2 cache.  */
+   32,					/* size of prefetch block */
+@@ -4150,6 +4151,17 @@
+       opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
+     }
+ 
++  /* Stack realignment without -maccumulate-outgoing-args requires %ebp,
++     so enable -maccumulate-outgoing-args when %ebp is fixed.  */
++  if (fixed_regs[BP_REG]
++      && !(opts->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
++    {
++      if (opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
++	warning (0, "fixed ebp register requires %saccumulate-outgoing-args%s",
++		 prefix, suffix);
++      opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
++    }
++
+   /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix.  */
+   {
+     char *p;
+@@ -4982,12 +4994,14 @@
+       /* If we are using the default tune= or arch=, undo the string assigned,
+ 	 and use the default.  */
+       if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH])
+-	opts->x_ix86_arch_string = option_strings[IX86_FUNCTION_SPECIFIC_ARCH];
++	opts->x_ix86_arch_string
++	  = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]);
+       else if (!orig_arch_specified)
+ 	opts->x_ix86_arch_string = NULL;
+ 
+       if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
+-	opts->x_ix86_tune_string = option_strings[IX86_FUNCTION_SPECIFIC_TUNE];
++	opts->x_ix86_tune_string
++	  = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]);
+       else if (orig_tune_defaulted)
+ 	opts->x_ix86_tune_string = NULL;
+ 
+@@ -9677,6 +9691,10 @@
+   if (TARGET_64BIT_MS_ABI && get_frame_size () > SEH_MAX_FRAME_SIZE)
+     return true;
+ 
++  /* SSE saves require frame-pointer when stack is misaligned.  */
++  if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
++    return true;
++  
+   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
+      turns off the frame pointer by default.  Turn it back on now if
+      we've not got a leaf function.  */
+@@ -10114,18 +10132,6 @@
+       crtl->preferred_stack_boundary = 128;
+       crtl->stack_alignment_needed = 128;
+     }
+-  /* preferred_stack_boundary is never updated for call
+-     expanded from tls descriptor. Update it here. We don't update it in
+-     expand stage because according to the comments before
+-     ix86_current_function_calls_tls_descriptor, tls calls may be optimized
+-     away.  */
+-  else if (ix86_current_function_calls_tls_descriptor
+-	   && crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
+-    {
+-      crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+-      if (crtl->stack_alignment_needed < PREFERRED_STACK_BOUNDARY)
+-	crtl->stack_alignment_needed = PREFERRED_STACK_BOUNDARY;
+-    }
+ 
+   stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
+   preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
+@@ -10799,6 +10805,11 @@
+       && cfun->stdarg
+       && crtl->stack_alignment_estimated < 128)
+     crtl->stack_alignment_estimated = 128;
++
++  /* __tls_get_addr needs to be called with 16-byte aligned stack.  */
++  if (ix86_tls_descriptor_calls_expanded_in_cfun
++      && crtl->preferred_stack_boundary < 128)
++    crtl->preferred_stack_boundary = 128;
+ }
+ 
+ /* Handle the TARGET_GET_DRAP_RTX hook.  Return NULL if no DRAP is
+@@ -11258,10 +11269,11 @@
+   unsigned int incoming_stack_boundary
+     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
+        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
+-  unsigned int stack_realign = (incoming_stack_boundary
+-				< (crtl->is_leaf
+-				   ? crtl->max_used_stack_slot_alignment
+-				   : crtl->stack_alignment_needed));
++  unsigned int stack_realign
++    = (incoming_stack_boundary
++       < (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
++	  ? crtl->max_used_stack_slot_alignment
++	  : crtl->stack_alignment_needed));
+ 
+   if (crtl->stack_realign_finalized)
+     {
+@@ -24365,7 +24377,7 @@
+        if (DYNAMIC_CHECK)
+ 	 Round COUNT down to multiple of SIZE
+        << optional caller supplied zero size guard is here >>
+-       << optional caller suppplied dynamic check is here >>
++       << optional caller supplied dynamic check is here >>
+        << caller supplied main copy loop is here >>
+      }
+    done_label:
+@@ -24539,8 +24551,8 @@
+       else
+ 	*min_size = 0;
+ 
+-      /* Our loops always round down the bock size, but for dispatch to library
+-	 we need precise value.  */
++      /* Our loops always round down the block size, but for dispatch to
++         library we need precise value.  */
+       if (dynamic_check)
+ 	*count = expand_simple_binop (GET_MODE (*count), AND, *count,
+ 				      GEN_INT (-size), *count, 1, OPTAB_DIRECT);
+@@ -25118,6 +25130,13 @@
+   size_needed = GET_MODE_SIZE (move_mode) * unroll_factor;
+   epilogue_size_needed = size_needed;
+ 
++  /* If we are going to call any library calls conditionally, make sure any
++     pending stack adjustment happen before the first conditional branch,
++     otherwise they will be emitted before the library call only and won't
++     happen from the other branches.  */
++  if (dynamic_check != -1)
++    do_pending_stack_adjust ();
++
+   desired_align = decide_alignment (align, alg, expected_size, move_mode);
+   if (!TARGET_ALIGN_STRINGOPS || noalign)
+     align = desired_align;
+@@ -38246,7 +38265,11 @@
+       memory = 0;
+       break;
+     case VOID_FTYPE_PV8DF_V8DF_QI:
++    case VOID_FTYPE_PV4DF_V4DF_QI:
++    case VOID_FTYPE_PV2DF_V2DF_QI:
+     case VOID_FTYPE_PV16SF_V16SF_HI:
++    case VOID_FTYPE_PV8SF_V8SF_QI:
++    case VOID_FTYPE_PV4SF_V4SF_QI:
+     case VOID_FTYPE_PV8DI_V8DI_QI:
+     case VOID_FTYPE_PV4DI_V4DI_QI:
+     case VOID_FTYPE_PV2DI_V2DI_QI:
+@@ -38306,10 +38329,6 @@
+     case VOID_FTYPE_PV16QI_V16QI_HI:
+     case VOID_FTYPE_PV32QI_V32QI_SI:
+     case VOID_FTYPE_PV64QI_V64QI_DI:
+-    case VOID_FTYPE_PV4DF_V4DF_QI:
+-    case VOID_FTYPE_PV2DF_V2DF_QI:
+-    case VOID_FTYPE_PV8SF_V8SF_QI:
+-    case VOID_FTYPE_PV4SF_V4SF_QI:
+       nargs = 2;
+       klass = store;
+       /* Reserve memory operand for target.  */
+@@ -40246,13 +40265,12 @@
+ 
+       op0 = fixup_modeless_constant (op0, mode0);
+ 
+-      if (GET_MODE (op0) == mode0
+-	  || (GET_MODE (op0) == VOIDmode && op0 != constm1_rtx))
++      if (GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
+ 	{
+ 	  if (!insn_data[icode].operand[0].predicate (op0, mode0))
+ 	    op0 = copy_to_mode_reg (mode0, op0);
+ 	}
+-      else if (op0 != constm1_rtx)
++      else
+ 	{
+ 	  op0 = copy_to_reg (op0);
+ 	  op0 = simplify_gen_subreg (mode0, op0, GET_MODE (op0), 0);
+@@ -45078,6 +45096,7 @@
+ 	{
+ 	  /* For SSE1, we have to reuse the V4SF code.  */
+ 	  rtx t = gen_reg_rtx (V4SFmode);
++	  emit_move_insn (t, gen_lowpart (V4SFmode, target));
+ 	  ix86_expand_vector_set (false, t, gen_lowpart (SFmode, val), elt);
+ 	  emit_move_insn (target, gen_lowpart (mode, t));
+ 	}
+--- a/gcc/config/i386/sse.md	2015-10-12 13:03:56.000000000 +0200
++++ b/gcc/config/i386/sse.md	2016-02-16 15:36:06.040607163 +0100
+@@ -804,7 +804,7 @@
+ 
+ (define_insn "*mov<mode>_internal"
+   [(set (match_operand:VMOVE 0 "nonimmediate_operand"               "=v,v ,m")
+-	(match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand"  "C ,vm,v"))]
++	(match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand"  "BC,vm,v"))]
+   "TARGET_SSE
+    && (register_operand (operands[0], <MODE>mode)
+        || register_operand (operands[1], <MODE>mode))"
+@@ -1022,7 +1022,7 @@
+       sse_suffix = "<ssescalarsize>";
+     }
+ 
+-  if (misaligned_operand (operands[1], <MODE>mode))
++  if (misaligned_operand (operands[0], <MODE>mode))
+     align = "u";
+   else
+     align = "a";
+@@ -2605,7 +2605,7 @@
+ 	(match_operator:<avx512fmaskmode> 3 "sse_comparison_operator"
+ 	  [(match_operand:VF 1 "register_operand" "v")
+ 	   (match_operand:VF 2 "nonimmediate_operand" "vm")]))]
+-  "TARGET_SSE"
++  "TARGET_AVX512F"
+   "vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+   [(set_attr "type" "ssecmp")
+    (set_attr "length_immediate" "1")
+@@ -3855,7 +3855,7 @@
+   "@
+    cvtsi2ss\t{%2, %0|%0, %2}
+    cvtsi2ss\t{%2, %0|%0, %2}
+-   vcvtsi2ss\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
++   vcvtsi2ss\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
+   [(set_attr "isa" "noavx,noavx,avx")
+    (set_attr "type" "sseicvt")
+    (set_attr "athlon_decode" "vector,double,*")
+@@ -3876,7 +3876,7 @@
+   "@
+    cvtsi2ssq\t{%2, %0|%0, %2}
+    cvtsi2ssq\t{%2, %0|%0, %2}
+-   vcvtsi2ssq\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
++   vcvtsi2ssq\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
+   [(set_attr "isa" "noavx,noavx,avx")
+    (set_attr "type" "sseicvt")
+    (set_attr "athlon_decode" "vector,double,*")
+@@ -3989,7 +3989,7 @@
+ 	  (match_operand:VF_128 1 "register_operand" "v")
+ 	  (const_int 1)))]
+   "TARGET_AVX512F && <round_modev4sf_condition>"
+-  "vcvtusi2<ssescalarmodesuffix>\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
++  "vcvtusi2<ssescalarmodesuffix>\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
+   [(set_attr "type" "sseicvt")
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "<ssescalarmode>")])
+@@ -4003,7 +4003,7 @@
+ 	  (match_operand:VF_128 1 "register_operand" "v")
+ 	  (const_int 1)))]
+   "TARGET_AVX512F && TARGET_64BIT"
+-  "vcvtusi2<ssescalarmodesuffix>\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
++  "vcvtusi2<ssescalarmodesuffix>\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
+   [(set_attr "type" "sseicvt")
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "<ssescalarmode>")])
+@@ -4268,7 +4268,7 @@
+   "@
+    cvtsi2sdq\t{%2, %0|%0, %2}
+    cvtsi2sdq\t{%2, %0|%0, %2}
+-   vcvtsi2sdq\t{<round_op3>%2, %1, %0|%0, %1, %2<round_op3>}"
++   vcvtsi2sdq\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
+   [(set_attr "isa" "noavx,noavx,avx")
+    (set_attr "type" "sseicvt")
+    (set_attr "athlon_decode" "double,direct,*")
+@@ -7018,28 +7018,50 @@
+   DONE;
+ })
+ 
+-(define_insn "vec_extract_hi_<mode><mask_name>"
+-  [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=v,<store_mask_constraint>")
++(define_insn "vec_extract_hi_<mode>_maskm"
++  [(set (match_operand:<ssehalfvecmode> 0 "memory_operand" "=m")
++	(vec_merge:<ssehalfvecmode>
++	  (vec_select:<ssehalfvecmode>
++	    (match_operand:VI8F_256 1 "register_operand" "v")
++	    (parallel [(const_int 2) (const_int 3)]))
++	  (match_operand:<ssehalfvecmode> 2 "memory_operand" "0")
++	  (match_operand:<ssehalfvecmode> 3 "register_operand" "k")))]
++  "TARGET_AVX512DQ && TARGET_AVX512VL
++   && rtx_equal_p (operands[2], operands[0])"
++  "vextract<shuffletype>64x2\t{$0x1, %1, %0%{%3%}|%0%{%3%}, %1, 0x1}"
++  [(set_attr "type" "sselog1")
++   (set_attr "length_immediate" "1")
++   (set_attr "prefix" "evex")
++   (set_attr "mode" "<sseinsnmode>")])
++
++(define_insn "vec_extract_hi_<mode>_mask"
++  [(set (match_operand:<ssehalfvecmode> 0 "register_operand" "=v")
++	(vec_merge:<ssehalfvecmode>
++	  (vec_select:<ssehalfvecmode>
++	    (match_operand:VI8F_256 1 "register_operand" "v")
++	    (parallel [(const_int 2) (const_int 3)]))
++	  (match_operand:<ssehalfvecmode> 2 "vector_move_operand" "0C")
++	  (match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
++  "TARGET_AVX512VL && TARGET_AVX512DQ"
++  "vextract<shuffletype>64x2\t{$0x1, %1, %0%{%3%}%N2|%0%{%3%}%N2, %1, 0x1}"
++  [(set_attr "type" "sselog1")
++   (set_attr "length_immediate" "1")
++   (set_attr "prefix" "evex")
++   (set_attr "mode" "<sseinsnmode>")])
++
++(define_insn "vec_extract_hi_<mode>"
++  [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=xm, vm")
+ 	(vec_select:<ssehalfvecmode>
+-	  (match_operand:VI8F_256 1 "register_operand" "v,v")
++	  (match_operand:VI8F_256 1 "register_operand" "x, v")
+ 	  (parallel [(const_int 2) (const_int 3)])))]
+-  "TARGET_AVX && <mask_avx512vl_condition> && <mask_avx512dq_condition>"
+-{
+-  if (TARGET_AVX512VL)
+-  {
+-    if (TARGET_AVX512DQ)
+-      return "vextract<shuffletype>64x2\t{$0x1, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x1}";
+-    else
+-      return "vextract<shuffletype>32x4\t{$0x1, %1, %0|%0, %1, 0x1}";
+-  }
+-  else
+-    return "vextract<i128>\t{$0x1, %1, %0|%0, %1, 0x1}";
+-}
+-  [(set_attr "type" "sselog")
+-   (set_attr "prefix_extra" "1")
++  "TARGET_AVX"
++  "@
++    vextract<i128>\t{$0x1, %1, %0|%0, %1, 0x1}
++    vextract<shuffletype>64x2\t{$0x1, %1, %0|%0, %1, 0x1}"
++  [(set_attr "isa" "*, avx512dq")
++   (set_attr "prefix" "vex, evex")
++   (set_attr "type" "sselog1")
+    (set_attr "length_immediate" "1")
+-   (set_attr "memory" "none,store")
+-   (set_attr "prefix" "vex")
+    (set_attr "mode" "<sseinsnmode>")])
+ 
+ (define_split
+@@ -15188,7 +15210,7 @@
+ 
+ (define_expand "avx512pf_gatherpf<mode>sf"
+   [(unspec
+-     [(match_operand:<avx512fmaskmode> 0 "register_or_constm1_operand")
++     [(match_operand:<avx512fmaskmode> 0 "register_operand")
+       (mem:<GATHER_SCATTER_SF_MEM_MODE>
+ 	(match_par_dup 5
+ 	  [(match_operand 2 "vsib_address_operand")
+@@ -15230,37 +15252,10 @@
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "XI")])
+ 
+-(define_insn "*avx512pf_gatherpf<mode>sf"
+-  [(unspec
+-     [(const_int -1)
+-      (match_operator:<GATHER_SCATTER_SF_MEM_MODE> 4 "vsib_mem_operator"
+-	[(unspec:P
+-	   [(match_operand:P 1 "vsib_address_operand" "Tv")
+-	    (match_operand:VI48_512 0 "register_operand" "v")
+-	    (match_operand:SI 2 "const1248_operand" "n")]
+-	   UNSPEC_VSIBADDR)])
+-      (match_operand:SI 3 "const_2_to_3_operand" "n")]
+-     UNSPEC_GATHER_PREFETCH)]
+-  "TARGET_AVX512PF"
+-{
+-  switch (INTVAL (operands[3]))
+-    {
+-    case 3:
+-      return "vgatherpf0<ssemodesuffix>ps\t{%4|%4}";
+-    case 2:
+-      return "vgatherpf1<ssemodesuffix>ps\t{%4|%4}";
+-    default:
+-      gcc_unreachable ();
+-    }
+-}
+-  [(set_attr "type" "sse")
+-   (set_attr "prefix" "evex")
+-   (set_attr "mode" "XI")])
+-
+ ;; Packed double variants
+ (define_expand "avx512pf_gatherpf<mode>df"
+   [(unspec
+-     [(match_operand:<avx512fmaskmode> 0 "register_or_constm1_operand")
++     [(match_operand:<avx512fmaskmode> 0 "register_operand")
+       (mem:V8DF
+ 	(match_par_dup 5
+ 	  [(match_operand 2 "vsib_address_operand")
+@@ -15302,37 +15297,10 @@
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "XI")])
+ 
+-(define_insn "*avx512pf_gatherpf<mode>df"
+-  [(unspec
+-     [(const_int -1)
+-      (match_operator:V8DF 4 "vsib_mem_operator"
+-	[(unspec:P
+-	   [(match_operand:P 1 "vsib_address_operand" "Tv")
+-	    (match_operand:VI4_256_8_512 0 "register_operand" "v")
+-	    (match_operand:SI 2 "const1248_operand" "n")]
+-	   UNSPEC_VSIBADDR)])
+-      (match_operand:SI 3 "const_2_to_3_operand" "n")]
+-     UNSPEC_GATHER_PREFETCH)]
+-  "TARGET_AVX512PF"
+-{
+-  switch (INTVAL (operands[3]))
+-    {
+-    case 3:
+-      return "vgatherpf0<ssemodesuffix>pd\t{%4|%4}";
+-    case 2:
+-      return "vgatherpf1<ssemodesuffix>pd\t{%4|%4}";
+-    default:
+-      gcc_unreachable ();
+-    }
+-}
+-  [(set_attr "type" "sse")
+-   (set_attr "prefix" "evex")
+-   (set_attr "mode" "XI")])
+-
+ ;; Packed float variants
+ (define_expand "avx512pf_scatterpf<mode>sf"
+   [(unspec
+-     [(match_operand:<avx512fmaskmode> 0 "register_or_constm1_operand")
++     [(match_operand:<avx512fmaskmode> 0 "register_operand")
+       (mem:<GATHER_SCATTER_SF_MEM_MODE>
+ 	(match_par_dup 5
+ 	  [(match_operand 2 "vsib_address_operand")
+@@ -15376,39 +15344,10 @@
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "XI")])
+ 
+-(define_insn "*avx512pf_scatterpf<mode>sf"
+-  [(unspec
+-     [(const_int -1)
+-      (match_operator:<GATHER_SCATTER_SF_MEM_MODE> 4 "vsib_mem_operator"
+-	[(unspec:P
+-	   [(match_operand:P 1 "vsib_address_operand" "Tv")
+-	    (match_operand:VI48_512 0 "register_operand" "v")
+-	    (match_operand:SI 2 "const1248_operand" "n")]
+-	   UNSPEC_VSIBADDR)])
+-      (match_operand:SI 3 "const2367_operand" "n")]
+-     UNSPEC_SCATTER_PREFETCH)]
+-  "TARGET_AVX512PF"
+-{
+-  switch (INTVAL (operands[3]))
+-    {
+-    case 3:
+-    case 7:
+-      return "vscatterpf0<ssemodesuffix>ps\t{%4|%4}";
+-    case 2:
+-    case 6:
+-      return "vscatterpf1<ssemodesuffix>ps\t{%4|%4}";
+-    default:
+-      gcc_unreachable ();
+-    }
+-}
+-  [(set_attr "type" "sse")
+-   (set_attr "prefix" "evex")
+-   (set_attr "mode" "XI")])
+-
+ ;; Packed double variants
+ (define_expand "avx512pf_scatterpf<mode>df"
+   [(unspec
+-     [(match_operand:<avx512fmaskmode> 0 "register_or_constm1_operand")
++     [(match_operand:<avx512fmaskmode> 0 "register_operand")
+       (mem:V8DF
+ 	(match_par_dup 5
+ 	  [(match_operand 2 "vsib_address_operand")
+@@ -15452,35 +15391,6 @@
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "XI")])
+ 
+-(define_insn "*avx512pf_scatterpf<mode>df"
+-  [(unspec
+-     [(const_int -1)
+-      (match_operator:V8DF 4 "vsib_mem_operator"
+-	[(unspec:P
+-	   [(match_operand:P 1 "vsib_address_operand" "Tv")
+-	    (match_operand:VI4_256_8_512 0 "register_operand" "v")
+-	    (match_operand:SI 2 "const1248_operand" "n")]
+-	   UNSPEC_VSIBADDR)])
+-      (match_operand:SI 3 "const2367_operand" "n")]
+-     UNSPEC_SCATTER_PREFETCH)]
+-  "TARGET_AVX512PF"
+-{
+-  switch (INTVAL (operands[3]))
+-    {
+-    case 3:
+-    case 7:
+-      return "vscatterpf0<ssemodesuffix>pd\t{%4|%4}";
+-    case 2:
+-    case 6:
+-      return "vscatterpf1<ssemodesuffix>pd\t{%4|%4}";
+-    default:
+-      gcc_unreachable ();
+-    }
+-}
+-  [(set_attr "type" "sse")
+-   (set_attr "prefix" "evex")
+-   (set_attr "mode" "XI")])
+-
+ (define_insn "avx512er_exp2<mode><mask_name><round_saeonly_name>"
+   [(set (match_operand:VF_512 0 "register_operand" "=v")
+ 	(unspec:VF_512
+@@ -16907,20 +16817,21 @@
+    (set_attr "mode" "<sseinsnmode>")])
+ 
+ (define_insn "vec_dup<mode>"
+-  [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x,v,x")
++  [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x,x,v,x")
+ 	(vec_duplicate:AVX_VEC_DUP_MODE
+-	  (match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,m,v,?x")))]
++	  (match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,m,x,v,?x")))]
+   "TARGET_AVX"
+   "@
+    v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0|%0, %1}
+    vbroadcast<ssescalarmodesuffix>\t{%1, %0|%0, %1}
+    v<sseintprefix>broadcast<bcstscalarsuff>\t{%x1, %0|%0, %x1}
++   v<sseintprefix>broadcast<bcstscalarsuff>\t{%x1, %g0|%g0, %x1}
+    #"
+   [(set_attr "type" "ssemov")
+    (set_attr "prefix_extra" "1")
+    (set_attr "prefix" "maybe_evex")
+-   (set_attr "isa" "avx2,noavx2,avx2,noavx2")
+-   (set_attr "mode" "<sseinsnmode>,V8SF,<sseinsnmode>,V8SF")])
++   (set_attr "isa" "avx2,noavx2,avx2,avx512f,noavx2")
++   (set_attr "mode" "<sseinsnmode>,V8SF,<sseinsnmode>,<sseinsnmode>,V8SF")])
+ 
+ (define_split
+   [(set (match_operand:AVX2_VEC_DUP_MODE 0 "register_operand")
+@@ -18524,7 +18435,7 @@
+ 	   (match_operand:SI 3 "const_0_to_15_operand")]
+ 	  UNSPEC_RANGE))]
+   "TARGET_AVX512DQ && <round_saeonly_mode512bit_condition>"
+-  "vrange<ssemodesuffix>\t{<round_saeonly_mask_op4>%3, %2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2, %3<round_saeonly_mask_op4>}"
++  "vrange<ssemodesuffix>\t{%3, <round_saeonly_mask_op4>%2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2<round_saeonly_mask_op4>, %3}"
+   [(set_attr "type" "sse")
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "<MODE>")])
+@@ -18540,7 +18451,7 @@
+ 	  (match_dup 1)
+ 	  (const_int 1)))]
+   "TARGET_AVX512DQ"
+-  "vrange<ssescalarmodesuffix>\t{<round_saeonly_op4>%3, %2, %1, %0|%0, %1, %2, %3<round_saeonly_op4>}"
++  "vrange<ssescalarmodesuffix>\t{%3, <round_saeonly_op4>%2, %1, %0|%0, %1, %2<round_saeonly_op4>, %3}"
+   [(set_attr "type" "sse")
+    (set_attr "prefix" "evex")
+    (set_attr "mode" "<MODE>")])
+--- a/gcc/cp/call.c	2015-10-21 11:27:12.000000000 +0200
++++ b/gcc/cp/call.c	2016-02-16 15:43:40.979927276 +0100
+@@ -213,7 +213,6 @@
+ 	 tree, int, tsubst_flags_t);
+ static conversion *implicit_conversion (tree, tree, tree, bool, int,
+ 					tsubst_flags_t);
+-static conversion *standard_conversion (tree, tree, tree, bool, int);
+ static conversion *reference_binding (tree, tree, tree, bool, int,
+ 				      tsubst_flags_t);
+ static conversion *build_conv (conversion_kind, tree, conversion *);
+@@ -1106,7 +1105,7 @@
+ 
+ static conversion *
+ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
+-		     int flags)
++		     int flags, tsubst_flags_t complain)
+ {
+   enum tree_code fcode, tcode;
+   conversion *conv;
+@@ -1136,7 +1135,7 @@
+       else if (TREE_CODE (to) == BOOLEAN_TYPE)
+ 	{
+ 	  /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961).  */
+-	  expr = resolve_nondeduced_context (expr);
++	  expr = resolve_nondeduced_context (expr, complain);
+ 	  from = TREE_TYPE (expr);
+ 	}
+     }
+@@ -1175,7 +1174,8 @@
+ 	 the standard conversion sequence to perform componentwise
+ 	 conversion.  */
+       conversion *part_conv = standard_conversion
+-	(TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags);
++	(TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags,
++	 complain);
+ 
+       if (part_conv)
+ 	{
+@@ -1814,7 +1814,7 @@
+   if (TREE_CODE (to) == REFERENCE_TYPE)
+     conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
+   else
+-    conv = standard_conversion (to, from, expr, c_cast_p, flags);
++    conv = standard_conversion (to, from, expr, c_cast_p, flags, complain);
+ 
+   if (conv)
+     return conv;
+@@ -7031,6 +7031,9 @@
+       && resolves_to_fixed_type_p (target, NULL))
+     return false;
+   tree init = TARGET_EXPR_INITIAL (exp);
++  /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR.  */
++  while (TREE_CODE (init) == COMPOUND_EXPR)
++    init = TREE_OPERAND (init, 1);
+   return (TREE_CODE (init) == AGGR_INIT_EXPR
+ 	  && !AGGR_INIT_VIA_CTOR_P (init));
+ }
+--- a/gcc/cp/constexpr.c	2015-11-25 20:56:06.000000000 +0100
++++ b/gcc/cp/constexpr.c	2016-02-16 15:44:57.410234482 +0100
+@@ -2110,7 +2110,8 @@
+   gcc_assert (ctx->ctor);
+   gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ 	      (type, TREE_TYPE (ctx->ctor)));
+-  gcc_assert (CONSTRUCTOR_NELTS (ctx->ctor) == 0);
++  /* We used to check that ctx->ctor was empty, but that isn't the case when
++     the object is zero-initialized before calling the constructor.  */
+   if (ctx->object)
+     gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ 		(type, TREE_TYPE (ctx->object)));
+@@ -3114,7 +3115,8 @@
+ 	r = TARGET_EXPR_INITIAL (r);
+       if (TREE_CODE (r) == VAR_DECL)
+ 	if (tree *p = ctx->values->get (r))
+-	  r = *p;
++	  if (*p != NULL_TREE)
++	    r = *p;
+       if (DECL_P (r))
+ 	{
+ 	  if (!ctx->quiet)
+--- a/gcc/cp/cp-tree.h	2015-11-26 11:21:42.000000000 +0100
++++ b/gcc/cp/cp-tree.h	2016-02-16 15:43:40.980927293 +0100
+@@ -5792,7 +5792,7 @@
+ extern tree get_template_innermost_arguments	(const_tree);
+ extern tree get_template_argument_pack_elems	(const_tree);
+ extern tree get_function_template_decl		(const_tree);
+-extern tree resolve_nondeduced_context		(tree);
++extern tree resolve_nondeduced_context		(tree, tsubst_flags_t);
+ extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
+ 
+ /* in repo.c */
+--- a/gcc/cp/cvt.c	2015-08-14 18:33:10.000000000 +0200
++++ b/gcc/cp/cvt.c	2016-02-16 15:43:40.980927293 +0100
+@@ -1260,7 +1260,7 @@
+ 
+     default:;
+     }
+-  expr = resolve_nondeduced_context (expr);
++  expr = resolve_nondeduced_context (expr, complain);
+   {
+     tree probe = expr;
+ 
+--- a/gcc/cp/decl2.c	2015-11-25 22:13:00.000000000 +0100
++++ b/gcc/cp/decl2.c	2016-02-16 15:16:42.697404077 +0100
+@@ -4197,6 +4197,9 @@
+     return false;
+   if (DECL_DECLARED_CONSTEXPR_P (decl))
+     return true;
++  if (DECL_HAS_VALUE_EXPR_P (decl))
++    /* A proxy isn't constant.  */
++    return false;
+   return (CP_TYPE_CONST_NON_VOLATILE_P (type)
+ 	  && INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+ }
+--- a/gcc/cp/decl.c	2015-11-19 17:34:32.000000000 +0100
++++ b/gcc/cp/decl.c	2016-02-16 15:43:40.982927327 +0100
+@@ -6436,7 +6436,7 @@
+       if (TREE_CODE (d_init) == TREE_LIST)
+ 	d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
+ 						  tf_warning_or_error);
+-      d_init = resolve_nondeduced_context (d_init);
++      d_init = resolve_nondeduced_context (d_init, tf_warning_or_error);
+       type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+ 						   auto_node);
+       if (type == error_mark_node)
+@@ -7360,7 +7360,8 @@
+ 
+   /* Don't get confused by a CONSTRUCTOR for some other type.  */
+   if (initial_value && TREE_CODE (initial_value) == CONSTRUCTOR
+-      && !BRACE_ENCLOSED_INITIALIZER_P (initial_value))
++      && !BRACE_ENCLOSED_INITIALIZER_P (initial_value)
++      && TREE_CODE (TREE_TYPE (initial_value)) != ARRAY_TYPE)
+     return 1;
+ 
+   if (initial_value)
+--- a/gcc/cp/init.c	2015-10-21 11:27:18.000000000 +0200
++++ b/gcc/cp/init.c	2016-02-16 15:43:40.983927344 +0100
+@@ -2079,6 +2079,11 @@
+ 	      && (TREE_CODE (init) == CONSTRUCTOR
+ 		  || TREE_CODE (init) == STRING_CST)))
+ 	break;
++      /* Don't return a CONSTRUCTOR for a variable with partial run-time
++	 initialization, since it doesn't represent the entire value.  */
++      if (TREE_CODE (init) == CONSTRUCTOR
++	  && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
++	break;
+       decl = unshare_expr (init);
+     }
+   return decl;
+@@ -3026,7 +3031,7 @@
+       if (auto_node)
+ 	{
+ 	  tree d_init = (**init)[0];
+-	  d_init = resolve_nondeduced_context (d_init);
++	  d_init = resolve_nondeduced_context (d_init, complain);
+ 	  type = do_auto_deduction (type, d_init, auto_node);
+ 	}
+     }
+--- a/gcc/cp/mangle.c	2015-11-25 22:13:00.000000000 +0100
++++ b/gcc/cp/mangle.c	2016-02-16 15:00:40.480184751 +0100
+@@ -1160,7 +1160,7 @@
+      So, for the example above, `Outer<int>::Inner' is represented as a
+      substitution candidate by a TREE_LIST whose purpose is `Outer<int>'
+      and whose value is `Outer<T>::Inner<U>'.  */
+-  if (TYPE_P (context))
++  if (context && TYPE_P (context))
+     substitution = build_tree_list (context, templ);
+   else
+     substitution = templ;
+--- a/gcc/cp/method.c	2015-02-10 17:38:31.000000000 +0100
++++ b/gcc/cp/method.c	2016-02-16 15:32:09.458536344 +0100
+@@ -1118,7 +1118,7 @@
+ static void
+ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
+ 		  bool *deleted_p, bool *constexpr_p,
+-		  bool diag, tree arg)
++		  bool diag, tree arg, bool dtor_from_ctor = false)
+ {
+   if (!fn || fn == error_mark_node)
+     goto bad;
+@@ -1130,7 +1130,7 @@
+       *spec_p = merge_exception_specifiers (*spec_p, raises);
+     }
+ 
+-  if (!trivial_fn_p (fn))
++  if (!trivial_fn_p (fn) && !dtor_from_ctor)
+     {
+       if (trivial_p)
+ 	*trivial_p = false;
+@@ -1163,14 +1163,17 @@
+ }
+ 
+ /* Subroutine of synthesized_method_walk to allow recursion into anonymous
+-   aggregates.  */
++   aggregates.  If DTOR_FROM_CTOR is true, we're walking subobject destructors
++   called from a synthesized constructor, in which case we don't consider
++   the triviality of the subobject destructor.  */
+ 
+ static void
+ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
+ 		   int quals, bool copy_arg_p, bool move_p,
+ 		   bool assign_p, tree *spec_p, bool *trivial_p,
+ 		   bool *deleted_p, bool *constexpr_p,
+-		   bool diag, int flags, tsubst_flags_t complain)
++		   bool diag, int flags, tsubst_flags_t complain,
++		   bool dtor_from_ctor)
+ {
+   tree field;
+   for (field = fields; field; field = DECL_CHAIN (field))
+@@ -1287,7 +1290,7 @@
+ 	  walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals,
+ 			     copy_arg_p, move_p, assign_p, spec_p, trivial_p,
+ 			     deleted_p, constexpr_p,
+-			     diag, flags, complain);
++			     diag, flags, complain, dtor_from_ctor);
+ 	  continue;
+ 	}
+ 
+@@ -1304,7 +1307,7 @@
+       rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);
+ 
+       process_subob_fn (rval, spec_p, trivial_p, deleted_p,
+-			constexpr_p, diag, field);
++			constexpr_p, diag, field, dtor_from_ctor);
+     }
+ }
+ 
+@@ -1487,7 +1490,7 @@
+ 	     dtors would be a double-fault).  */
+ 	  process_subob_fn (rval, NULL, NULL,
+ 			    deleted_p, NULL, false,
+-			    basetype);
++			    basetype, /*dtor_from_ctor*/true);
+ 	}
+ 
+       if (check_vdtor && type_has_virtual_destructor (basetype))
+@@ -1534,7 +1537,7 @@
+ 				      NULL_TREE, flags, complain);
+ 	      process_subob_fn (rval, NULL, NULL,
+ 				deleted_p, NULL, false,
+-				basetype);
++				basetype, /*dtor_from_ctor*/true);
+ 	    }
+ 	}
+     }
+@@ -1543,13 +1546,13 @@
+   walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals,
+ 		     copy_arg_p, move_p, assign_p, spec_p, trivial_p,
+ 		     deleted_p, constexpr_p,
+-		     diag, flags, complain);
++		     diag, flags, complain, /*dtor_from_ctor*/false);
+   if (ctor_p)
+     walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier,
+ 		       sfk_destructor, TYPE_UNQUALIFIED, false,
+ 		       false, false, NULL, NULL,
+ 		       deleted_p, NULL,
+-		       false, flags, complain);
++		       false, flags, complain, /*dtor_from_ctor*/true);
+ 
+   pop_scope (scope);
+ 
+--- a/gcc/cp/optimize.c	2015-11-25 22:13:00.000000000 +0100
++++ b/gcc/cp/optimize.c	2016-02-16 15:32:24.480825007 +0100
+@@ -670,6 +670,8 @@
+ 	{
+ 	  if (expand_or_defer_fn_1 (clone))
+ 	    emit_associated_thunks (clone);
++	  /* We didn't generate a body, so remove the empty one.  */
++	  DECL_SAVED_TREE (clone) = NULL_TREE;
+ 	}
+       else
+ 	expand_or_defer_fn (clone);
+--- a/gcc/cp/parser.c	2015-11-25 20:56:12.000000000 +0100
++++ b/gcc/cp/parser.c	2016-02-16 15:42:16.245497989 +0100
+@@ -15682,7 +15682,7 @@
+     {
+       /* Indicate whether this class was declared as a `class' or as a
+ 	 `struct'.  */
+-      if (TREE_CODE (type) == RECORD_TYPE)
++      if (CLASS_TYPE_P (type))
+ 	CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type);
+       cp_parser_check_class_key (tag_type, type);
+     }
+@@ -32359,6 +32359,7 @@
+       DECL_DECLARED_INLINE_P (fndecl) = 1;
+       DECL_IGNORED_P (fndecl) = 1;
+       DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
++      SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("<udr>"));
+       DECL_ATTRIBUTES (fndecl)
+ 	= tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
+ 		     DECL_ATTRIBUTES (fndecl));
+--- a/gcc/cp/pt.c	2015-11-25 20:56:12.000000000 +0100
++++ b/gcc/cp/pt.c	2016-02-16 15:43:40.985927378 +0100
+@@ -10095,12 +10095,16 @@
+ 	  if (PACK_EXPANSION_LOCAL_P (t))
+ 	    arg_pack = retrieve_local_specialization (parm_pack);
+ 	  else
++	    /* We can't rely on local_specializations for a parameter
++	       name used later in a function declaration (such as in a
++	       late-specified return type).  Even if it exists, it might
++	       have the wrong value for a recursive call.  */
++	    need_local_specializations = true;
++
++	  if (!arg_pack)
+ 	    {
+-	      /* We can't rely on local_specializations for a parameter
+-		 name used later in a function declaration (such as in a
+-		 late-specified return type).  Even if it exists, it might
+-		 have the wrong value for a recursive call.  Just make a
+-		 dummy decl, since it's only used for its type.  */
++	      /* This parameter pack was used in an unevaluated context.  Just
++		 make a dummy decl, since it's only used for its type.  */
+ 	      arg_pack = tsubst_decl (parm_pack, args, complain);
+ 	      if (arg_pack && DECL_PACK_P (arg_pack))
+ 		/* Partial instantiation of the parm_pack, we can't build
+@@ -10108,7 +10112,6 @@
+ 		arg_pack = NULL_TREE;
+ 	      else
+ 		arg_pack = make_fnparm_pack (arg_pack);
+-	      need_local_specializations = true;
+ 	    }
+ 	}
+       else if (TREE_CODE (parm_pack) == FIELD_DECL)
+@@ -13245,7 +13248,12 @@
+ 	  --c_inhibit_evaluation_warnings;
+ 
+ 	  if (TREE_CODE (expanded) == TREE_VEC)
+-	    len = TREE_VEC_LENGTH (expanded);
++	    {
++	      len = TREE_VEC_LENGTH (expanded);
++	      /* Set TREE_USED for the benefit of -Wunused.  */
++	      for (int i = 0; i < len; i++)
++		TREE_USED (TREE_VEC_ELT (expanded, i)) = true;
++	    }
+ 
+ 	  if (expanded == error_mark_node)
+ 	    return error_mark_node;
+@@ -17344,7 +17352,7 @@
+    lvalue for the function template specialization.  */
+ 
+ tree
+-resolve_nondeduced_context (tree orig_expr)
++resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
+ {
+   tree expr, offset, baselink;
+   bool addr;
+@@ -17427,16 +17435,16 @@
+ 	    {
+ 	      tree base
+ 		= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0)));
+-	      expr = build_offset_ref (base, expr, addr, tf_warning_or_error);
++	      expr = build_offset_ref (base, expr, addr, complain);
+ 	    }
+ 	  if (addr)
+-	    expr = cp_build_addr_expr (expr, tf_warning_or_error);
++	    expr = cp_build_addr_expr (expr, complain);
+ 	  return expr;
+ 	}
+-      else if (good == 0 && badargs)
++      else if (good == 0 && badargs && (complain & tf_error))
+ 	/* There were no good options and at least one bad one, so let the
+ 	   user know what the problem is.  */
+-	instantiate_template (badfn, badargs, tf_warning_or_error);
++	instantiate_template (badfn, badargs, complain);
+     }
+   return orig_expr;
+ }
+@@ -19469,6 +19477,38 @@
+   return decl;
+ }
+ 
++/* True iff the TEMPLATE_DECL tmpl is a partial specialization.  */
++
++static bool
++partial_specialization_p (tree tmpl)
++{
++  /* Any specialization has DECL_TEMPLATE_SPECIALIZATION.  */
++  if (!DECL_TEMPLATE_SPECIALIZATION (tmpl))
++    return false;
++  if (!VAR_P (DECL_TEMPLATE_RESULT (tmpl)))
++    return false;
++  tree t = DECL_TI_TEMPLATE (tmpl);
++  /* A specialization that fully specializes one of the containing classes is
++     not a partial specialization.  */
++  return (list_length (DECL_TEMPLATE_PARMS (tmpl))
++	  == list_length (DECL_TEMPLATE_PARMS (t)));
++}
++
++/* If TMPL is a partial specialization, return the arguments for its primary
++   template.  */
++
++static tree
++impartial_args (tree tmpl, tree args)
++{
++  if (!partial_specialization_p (tmpl))
++    return args;
++
++  /* If TMPL is a partial specialization, we need to substitute to get
++     the args for the primary template.  */
++  return tsubst_template_args (DECL_TI_ARGS (tmpl), args,
++			       tf_warning_or_error, tmpl);
++}
++
+ /* Return the most specialized of the template partial specializations
+    which can produce TARGET, a specialization of some class or variable
+    template.  The value returned is actually a TREE_LIST; the TREE_VALUE is
+@@ -20283,7 +20323,7 @@
+     return d;
+ 
+   gen_tmpl = most_general_template (tmpl);
+-  gen_args = DECL_TI_ARGS (d);
++  gen_args = impartial_args (tmpl, DECL_TI_ARGS (d));
+ 
+   if (tmpl != gen_tmpl)
+     /* We should already have the extra args.  */
+@@ -22341,7 +22381,7 @@
+ 	}
+     }
+ 
+-  init = resolve_nondeduced_context (init);
++  init = resolve_nondeduced_context (init, tf_warning_or_error);
+ 
+   targs = make_tree_vec (1);
+   if (AUTO_IS_DECLTYPE (auto_node))
+--- a/gcc/cp/rtti.c	2015-01-09 21:18:42.000000000 +0100
++++ b/gcc/cp/rtti.c	2016-02-16 15:43:40.986927395 +0100
+@@ -255,7 +255,7 @@
+   if (error_operand_p (exp))
+     return error_mark_node;
+ 
+-  exp = resolve_nondeduced_context (exp);
++  exp = resolve_nondeduced_context (exp, complain);
+ 
+   /* peel back references, so they match.  */
+   type = non_reference (TREE_TYPE (exp));
+@@ -345,7 +345,7 @@
+       /* So we need to look into the vtable of the type of exp.
+          Make sure it isn't a null lvalue.  */
+       exp = cp_build_addr_expr (exp, complain);
+-      exp = stabilize_reference (exp);
++      exp = save_expr (exp);
+       cond = cp_convert (boolean_type_node, exp, complain);
+       exp = cp_build_indirect_ref (exp, RO_NULL, complain);
+     }
+--- a/gcc/cp/semantics.c	2015-09-10 09:40:59.000000000 +0200
++++ b/gcc/cp/semantics.c	2016-02-16 15:43:40.987927412 +0100
+@@ -4104,9 +4104,8 @@
+       /* We don't want to process FN again, so pretend we've written
+ 	 it out, even though we haven't.  */
+       TREE_ASM_WRITTEN (fn) = 1;
+-      /* If this is an instantiation of a constexpr function, keep
+-	 DECL_SAVED_TREE for explain_invalid_constexpr_fn.  */
+-      if (!is_instantiation_of_constexpr (fn))
++      /* If this is a constexpr function, keep DECL_SAVED_TREE.  */
++      if (!DECL_DECLARED_CONSTEXPR_P (fn))
+ 	DECL_SAVED_TREE (fn) = NULL_TREE;
+       return false;
+     }
+@@ -7248,7 +7247,7 @@
+ 
+   /* The type denoted by decltype(e) is defined as follows:  */
+ 
+-  expr = resolve_nondeduced_context (expr);
++  expr = resolve_nondeduced_context (expr, complain);
+ 
+   if (invalid_nonstatic_memfn_p (expr, complain))
+     return error_mark_node;
+--- a/gcc/cp/tree.c	2015-07-16 15:25:25.000000000 +0200
++++ b/gcc/cp/tree.c	2016-02-16 15:13:32.730521942 +0100
+@@ -1007,7 +1007,8 @@
+    the C version of this function does not properly maintain canonical
+    types (which are not used in C).  */
+ tree
+-c_build_qualified_type (tree type, int type_quals)
++c_build_qualified_type (tree type, int type_quals, tree /* orig_qual_type */,
++			size_t /* orig_qual_indirect */)
+ {
+   return cp_build_qualified_type (type, type_quals);
+ }
+--- a/gcc/cp/typeck.c	2015-11-26 11:21:42.000000000 +0100
++++ b/gcc/cp/typeck.c	2016-02-16 15:43:40.988927429 +0100
+@@ -1926,7 +1926,7 @@
+ 
+   exp = mark_rvalue_use (exp);
+ 
+-  exp = resolve_nondeduced_context (exp);
++  exp = resolve_nondeduced_context (exp, complain);
+   if (type_unknown_p (exp))
+     {
+       if (complain & tf_error)
+@@ -4672,6 +4672,20 @@
+ 	      return error_mark_node;
+ 	    }
+ 
++	  /* It's not precisely specified how the usual arithmetic
++	     conversions apply to the vector types.  Here, we use
++	     the unsigned type if one of the operands is signed and
++	     the other one is unsigned.  */
++	  if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
++	    {
++	      if (!TYPE_UNSIGNED (type0))
++		op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
++	      else
++		op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
++	      warning_at (location, OPT_Wsign_compare, "comparison between "
++			  "types %qT and %qT", type0, type1);
++	    }
++
+ 	  /* Always construct signed integer vector type.  */
+ 	  intt = c_common_type_for_size (GET_MODE_BITSIZE
+ 					   (TYPE_MODE (TREE_TYPE (type0))), 0);
+--- a/gcc/dse.c	2015-01-22 18:59:23.000000000 +0100
++++ b/gcc/dse.c	2016-02-16 15:42:07.863357871 +0100
+@@ -1571,14 +1571,9 @@
+ 	mem_addr = base->val_rtx;
+       else
+ 	{
+-	  group_info_t group
+-	    = rtx_group_vec[group_id];
++	  group_info_t group = rtx_group_vec[group_id];
+ 	  mem_addr = group->canon_base_addr;
+ 	}
+-      /* get_addr can only handle VALUE but cannot handle expr like:
+-	 VALUE + OFFSET, so call get_addr to get original addr for
+-	 mem_addr before plus_constant.  */
+-      mem_addr = get_addr (mem_addr);
+       if (offset)
+ 	mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
+     }
+@@ -2188,14 +2183,9 @@
+ 	mem_addr = base->val_rtx;
+       else
+ 	{
+-	  group_info_t group
+-	    = rtx_group_vec[group_id];
++	  group_info_t group = rtx_group_vec[group_id];
+ 	  mem_addr = group->canon_base_addr;
+ 	}
+-      /* get_addr can only handle VALUE but cannot handle expr like:
+-	 VALUE + OFFSET, so call get_addr to get original addr for
+-	 mem_addr before plus_constant.  */
+-      mem_addr = get_addr (mem_addr);
+       if (offset)
+ 	mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
+     }
+--- a/gcc/dwarf2out.c	2015-11-09 19:27:43.000000000 +0100
++++ b/gcc/dwarf2out.c	2016-02-16 15:12:17.984964048 +0100
+@@ -20290,9 +20290,10 @@
+   /* We are going to output a DIE to represent the unqualified version
+      of this type (i.e. without any const or volatile qualifiers) so
+      get the main variant (i.e. the unqualified version) of this type
+-     now.  (Vectors are special because the debugging info is in the
++     now.  (Vectors and arrays are special because the debugging info is in the
+      cloned type itself).  */
+-  if (TREE_CODE (type) != VECTOR_TYPE)
++  if (TREE_CODE (type) != VECTOR_TYPE
++      && TREE_CODE (type) != ARRAY_TYPE)
+     type = type_main_variant (type);
+ 
+   /* If this is an array type with hidden descriptor, handle it first.  */
+--- a/gcc/emit-rtl.c	2015-08-05 13:20:59.000000000 +0200
++++ b/gcc/emit-rtl.c	2016-02-16 15:16:05.601653486 +0100
+@@ -5256,7 +5256,8 @@
+     {
+     case REG_EQUAL:
+     case REG_EQUIV:
+-      if (!set_for_reg_notes (insn))
++      /* We need to support the REG_EQUAL on USE trick of find_reloads.  */
++      if (!set_for_reg_notes (insn) && GET_CODE (PATTERN (insn)) != USE)
+ 	return NULL_RTX;
+ 
+       /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
+--- a/gcc/fold-const.c	2015-11-23 09:32:28.000000000 +0100
++++ b/gcc/fold-const.c	2016-02-16 15:42:00.259230970 +0100
+@@ -8731,20 +8731,6 @@
+   return total.to_uhwi () > (unsigned HOST_WIDE_INT) size;
+ }
+ 
+-/* Return the HOST_WIDE_INT least significant bits of T, a sizetype
+-   kind INTEGER_CST.  This makes sure to properly sign-extend the
+-   constant.  */
+-
+-static HOST_WIDE_INT
+-size_low_cst (const_tree t)
+-{
+-  HOST_WIDE_INT w = TREE_INT_CST_ELT (t, 0);
+-  int prec = TYPE_PRECISION (TREE_TYPE (t));
+-  if (prec < HOST_BITS_PER_WIDE_INT)
+-    return sext_hwi (w, prec);
+-  return w;
+-}
+-
+ /* Subroutine of fold_binary.  This routine performs all of the
+    transformations that are common to the equality/inequality
+    operators (EQ_EXPR and NE_EXPR) and the ordering operators
+@@ -8889,18 +8875,29 @@
+ 	  STRIP_SIGN_NOPS (base0);
+ 	  if (TREE_CODE (base0) == ADDR_EXPR)
+ 	    {
+-	      base0 = TREE_OPERAND (base0, 0);
+-	      indirect_base0 = true;
++	      base0
++		= get_inner_reference (TREE_OPERAND (base0, 0),
++				       &bitsize, &bitpos0, &offset0, &mode,
++				       &unsignedp, &volatilep, false);
++	      if (TREE_CODE (base0) == INDIRECT_REF)
++		base0 = TREE_OPERAND (base0, 0);
++	      else
++		indirect_base0 = true;
+ 	    }
+-	  offset0 = TREE_OPERAND (arg0, 1);
+-	  if (tree_fits_shwi_p (offset0))
+-	    {
+-	      HOST_WIDE_INT off = size_low_cst (offset0);
+-	      if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off)
+-				   * BITS_PER_UNIT)
+-		  / BITS_PER_UNIT == (HOST_WIDE_INT) off)
++	  if (offset0 == NULL_TREE || integer_zerop (offset0))
++	    offset0 = TREE_OPERAND (arg0, 1);
++	  else
++	    offset0 = size_binop (PLUS_EXPR, offset0,
++				  TREE_OPERAND (arg0, 1));
++	  if (TREE_CODE (offset0) == INTEGER_CST)
++	    {
++	      offset_int tem = wi::sext (wi::to_offset (offset0),
++					 TYPE_PRECISION (sizetype));
++	      tem = wi::lshift (tem, LOG2_BITS_PER_UNIT);
++	      tem += bitpos0;
++	      if (wi::fits_shwi_p (tem))
+ 		{
+-		  bitpos0 = off * BITS_PER_UNIT;
++		  bitpos0 = tem.to_shwi ();
+ 		  offset0 = NULL_TREE;
+ 		}
+ 	    }
+@@ -8923,18 +8920,29 @@
+ 	  STRIP_SIGN_NOPS (base1);
+ 	  if (TREE_CODE (base1) == ADDR_EXPR)
+ 	    {
+-	      base1 = TREE_OPERAND (base1, 0);
+-	      indirect_base1 = true;
++	      base1
++		= get_inner_reference (TREE_OPERAND (base1, 0),
++				       &bitsize, &bitpos1, &offset1, &mode,
++				       &unsignedp, &volatilep, false);
++	      if (TREE_CODE (base1) == INDIRECT_REF)
++		base1 = TREE_OPERAND (base1, 0);
++	      else
++		indirect_base1 = true;
+ 	    }
+-	  offset1 = TREE_OPERAND (arg1, 1);
+-	  if (tree_fits_shwi_p (offset1))
++	  if (offset1 == NULL_TREE || integer_zerop (offset1))
++	    offset1 = TREE_OPERAND (arg1, 1);
++	  else
++	    offset1 = size_binop (PLUS_EXPR, offset1,
++				  TREE_OPERAND (arg1, 1));
++	  if (TREE_CODE (offset1) == INTEGER_CST)
+ 	    {
+-	      HOST_WIDE_INT off = size_low_cst (offset1);
+-	      if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off)
+-				   * BITS_PER_UNIT)
+-		  / BITS_PER_UNIT == (HOST_WIDE_INT) off)
++	      offset_int tem = wi::sext (wi::to_offset (offset1),
++					 TYPE_PRECISION (sizetype));
++	      tem = wi::lshift (tem, LOG2_BITS_PER_UNIT);
++	      tem += bitpos1;
++	      if (wi::fits_shwi_p (tem))
+ 		{
+-		  bitpos1 = off * BITS_PER_UNIT;
++		  bitpos1 = tem.to_shwi ();
+ 		  offset1 = NULL_TREE;
+ 		}
+ 	    }
+@@ -12375,12 +12383,27 @@
+ 	      || POINTER_TYPE_P (TREE_TYPE (arg0))))
+ 	{
+ 	  tree val = TREE_OPERAND (arg0, 1);
+-	  return omit_two_operands_loc (loc, type,
+-				    fold_build2_loc (loc, code, type,
+-						 val,
+-						 build_int_cst (TREE_TYPE (val),
+-								0)),
+-				    TREE_OPERAND (arg0, 0), arg1);
++	  val = fold_build2_loc (loc, code, type, val,
++				 build_int_cst (TREE_TYPE (val), 0));
++	  return omit_two_operands_loc (loc, type, val,
++					TREE_OPERAND (arg0, 0), arg1);
++	}
++
++      /* Transform comparisons of the form X CMP X +- Y to Y CMP 0.  */
++      if ((TREE_CODE (arg1) == PLUS_EXPR
++	   || TREE_CODE (arg1) == POINTER_PLUS_EXPR
++	   || TREE_CODE (arg1) == MINUS_EXPR)
++	  && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1,
++									0)),
++			      arg0, 0)
++	  && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
++	      || POINTER_TYPE_P (TREE_TYPE (arg1))))
++	{
++	  tree val = TREE_OPERAND (arg1, 1);
++	  val = fold_build2_loc (loc, code, type, val,
++				 build_int_cst (TREE_TYPE (val), 0));
++	  return omit_two_operands_loc (loc, type, val,
++					TREE_OPERAND (arg1, 0), arg0);
+ 	}
+ 
+       /* Transform comparisons of the form C - X CMP X if C % 2 == 1.  */
+@@ -12390,12 +12413,22 @@
+ 									1)),
+ 			      arg1, 0)
+ 	  && wi::extract_uhwi (TREE_OPERAND (arg0, 0), 0, 1) == 1)
+-	{
+-	  return omit_two_operands_loc (loc, type,
+-				    code == NE_EXPR
+-				    ? boolean_true_node : boolean_false_node,
+-				    TREE_OPERAND (arg0, 1), arg1);
+-	}
++	return omit_two_operands_loc (loc, type,
++				      code == NE_EXPR
++				      ? boolean_true_node : boolean_false_node,
++				      TREE_OPERAND (arg0, 1), arg1);
++
++      /* Transform comparisons of the form X CMP C - X if C % 2 == 1.  */
++      if (TREE_CODE (arg1) == MINUS_EXPR
++	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == INTEGER_CST
++	  && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1,
++									1)),
++			      arg0, 0)
++	  && wi::extract_uhwi (TREE_OPERAND (arg1, 0), 0, 1) == 1)
++	return omit_two_operands_loc (loc, type,
++				      code == NE_EXPR
++				      ? boolean_true_node : boolean_false_node,
++				      TREE_OPERAND (arg1, 1), arg0);
+ 
+       /* Convert ABS_EXPR<x> == 0 or ABS_EXPR<x> != 0 to x == 0 or x != 0.  */
+       if (TREE_CODE (arg0) == ABS_EXPR
+--- a/gcc/fortran/check.c	2015-11-24 21:40:10.000000000 +0100
++++ b/gcc/fortran/check.c	2016-02-16 15:44:29.774760024 +0100
+@@ -1157,6 +1157,59 @@
+   return true;
+ }
+ 
++bool
++gfc_check_event_query (gfc_expr *event, gfc_expr *count, gfc_expr *stat)
++{
++  if (event->ts.type != BT_DERIVED
++      || event->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
++      || event->ts.u.derived->intmod_sym_id != ISOFORTRAN_EVENT_TYPE)
++    {
++      gfc_error ("EVENT argument at %L to the intrinsic EVENT_QUERY "
++		 "shall be of type EVENT_TYPE", &event->where);
++      return false;
++    }
++
++  if (!scalar_check (event, 0))
++    return false;
++
++  if (!gfc_check_vardef_context (count, false, false, false, NULL))
++    {
++      gfc_error ("COUNT argument of the EVENT_QUERY intrinsic function at %L "
++		 "shall be definable", &count->where);
++      return false;
++    }
++
++  if (!type_check (count, 1, BT_INTEGER))
++    return false;
++
++  int i = gfc_validate_kind (BT_INTEGER, count->ts.kind, false);
++  int j = gfc_validate_kind (BT_INTEGER, gfc_default_integer_kind, false);
++
++  if (gfc_integer_kinds[i].range < gfc_integer_kinds[j].range)
++    {
++      gfc_error ("COUNT argument of the EVENT_QUERY intrinsic function at %L "
++		 "shall have at least the range of the default integer",
++		 &count->where);
++      return false;
++    }
++
++  if (stat != NULL)
++    {
++      if (!type_check (stat, 2, BT_INTEGER))
++	return false;
++      if (!scalar_check (stat, 2))
++	return false;
++      if (!variable_check (stat, 2, false))
++	return false;
++
++      if (!gfc_notify_std (GFC_STD_F2008_TS, "STAT= argument to %s at %L",
++			   gfc_current_intrinsic, &stat->where))
++	return false;
++    }
++
++  return true;
++}
++
+ 
+ bool
+ gfc_check_atomic_fetch_op (gfc_expr *atom, gfc_expr *value, gfc_expr *old,
+--- a/gcc/fortran/decl.c	2015-11-13 22:28:10.000000000 +0100
++++ b/gcc/fortran/decl.c	2016-02-16 15:32:51.220338624 +0100
+@@ -6454,9 +6454,16 @@
+ 	  prev_ns = ns;
+ 	  ns = ns->sibling;
+ 	}
+-  
+-      gfc_free_namespace (gfc_current_ns);
+-      gfc_current_ns = parent_ns;
++
++      if (parent_ns)
++	{
++	  /* Free the current namespace only when the parent one exists.  This
++	     prevents an ICE when more END BLOCK then BLOCK statements are
++	     present.  It does not mean any further harm, because we already
++	     have errored.  */
++	  gfc_free_namespace (gfc_current_ns);
++	  gfc_current_ns = parent_ns;
++	}
+     }
+ 
+   return MATCH_ERROR;
+--- a/gcc/fortran/dump-parse-tree.c	2015-01-15 21:11:12.000000000 +0100
++++ b/gcc/fortran/dump-parse-tree.c	2016-02-16 15:44:29.774760024 +0100
+@@ -1659,6 +1659,33 @@
+ 	}
+       break;
+ 
++    case EXEC_EVENT_POST:
++    case EXEC_EVENT_WAIT:
++      if (c->op == EXEC_EVENT_POST)
++	fputs ("EVENT POST ", dumpfile);
++      else
++	fputs ("EVENT WAIT ", dumpfile);
++
++      fputs ("event-variable=", dumpfile);
++      if (c->expr1 != NULL)
++	show_expr (c->expr1);
++      if (c->expr4 != NULL)
++	{
++	  fputs (" until_count=", dumpfile);
++	  show_expr (c->expr4);
++	}
++      if (c->expr2 != NULL)
++	{
++	  fputs (" stat=", dumpfile);
++	  show_expr (c->expr2);
++	}
++      if (c->expr3 != NULL)
++	{
++	  fputs (" errmsg=", dumpfile);
++	  show_expr (c->expr3);
++	}
++      break;
++
+     case EXEC_LOCK:
+     case EXEC_UNLOCK:
+       if (c->op == EXEC_LOCK)
+--- a/gcc/fortran/expr.c	2015-11-18 17:29:58.000000000 +0100
++++ b/gcc/fortran/expr.c	2016-02-16 15:44:29.775760041 +0100
+@@ -4864,6 +4864,19 @@
+       return false;
+     }
+ 
++  /* TS18508, C702/C203.  */
++  if (!alloc_obj
++      && (attr.lock_comp
++	  || (e->ts.type == BT_DERIVED
++	      && e->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++	      && e->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)))
++    {
++      if (context)
++	gfc_error ("LOCK_EVENT in variable definition context (%s) at %L",
++		   context, &e->where);
++      return false;
++    }
++
+   /* INTENT(IN) dummy argument.  Check this, unless the object itself is the
+      component of sub-component of a pointer; we need to distinguish
+      assignment to a pointer component from pointer-assignment to a pointer
+--- a/gcc/fortran/gfortran.h	2015-04-10 13:29:53.000000000 +0200
++++ b/gcc/fortran/gfortran.h	2016-02-16 15:44:29.775760041 +0100
+@@ -253,7 +253,8 @@
+   ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
+   ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
+   ST_PROCEDURE, ST_GENERIC, ST_CRITICAL, ST_END_CRITICAL,
+-  ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_NONE
++  ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_EVENT_POST,
++  ST_EVENT_WAIT,ST_NONE
+ }
+ gfc_statement;
+ 
+@@ -413,6 +414,7 @@
+   GFC_ISYM_ERFC,
+   GFC_ISYM_ERFC_SCALED,
+   GFC_ISYM_ETIME,
++  GFC_ISYM_EVENT_QUERY,
+   GFC_ISYM_EXECUTE_COMMAND_LINE,
+   GFC_ISYM_EXIT,
+   GFC_ISYM_EXP,
+@@ -847,7 +849,7 @@
+      entities.  */
+   unsigned alloc_comp:1, pointer_comp:1, proc_pointer_comp:1,
+ 	   private_comp:1, zero_comp:1, coarray_comp:1, lock_comp:1,
+-	   defined_assign_comp:1, unlimited_polymorphic:1;
++	   event_comp:1, defined_assign_comp:1, unlimited_polymorphic:1;
+ 
+   /* This is a temporary selector for SELECT TYPE or an associate
+      variable for SELECT_TYPE or ASSOCIATE.  */
+@@ -2330,7 +2332,7 @@
+   EXEC_OPEN, EXEC_CLOSE, EXEC_WAIT,
+   EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END,
+   EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH,
+-  EXEC_LOCK, EXEC_UNLOCK,
++  EXEC_LOCK, EXEC_UNLOCK, EXEC_EVENT_POST, EXEC_EVENT_WAIT,
+   EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP,
+   EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA,
+   EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
+--- a/gcc/fortran/interface.c	2015-10-30 17:58:20.000000000 +0100
++++ b/gcc/fortran/interface.c	2016-02-16 15:44:29.777760075 +0100
+@@ -2144,6 +2144,21 @@
+ 		       formal->name, &actual->where);
+ 	  return 0;
+ 	}
++
++      /* TS18508, C702/C703.  */
++      if (formal->attr.intent != INTENT_INOUT
++	  && (((formal->ts.type == BT_DERIVED || formal->ts.type == BT_CLASS)
++	       && formal->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++	       && formal->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
++	      || formal->attr.event_comp))
++
++    	{
++	  if (where)
++	    gfc_error ("Actual argument to non-INTENT(INOUT) dummy %qs at %L, "
++		       "which is EVENT_TYPE or has a EVENT_TYPE component",
++		       formal->name, &actual->where);
++	  return 0;
++	}
+     }
+ 
+   /* F2008, C1239/C1240.  */
+@@ -3375,6 +3390,19 @@
+ 			 "component at %L requires an explicit interface for "
+ 			 "procedure %qs", &a->expr->where, sym->name);
+ 	      break;
++	    }
++
++	  if (a->expr
++	      && (a->expr->ts.type == BT_DERIVED || a->expr->ts.type == BT_CLASS)
++	      && ((a->expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++		   && a->expr->ts.u.derived->intmod_sym_id
++		      == ISOFORTRAN_EVENT_TYPE)
++		  || gfc_expr_attr (a->expr).event_comp))
++	    {
++	      gfc_error ("Actual argument of EVENT_TYPE or with EVENT_TYPE "
++			 "component at %L requires an explicit interface for "
++			 "procedure %qs", &a->expr->where, sym->name);
++	      break;
+ 	    }
+ 
+ 	  if (a->expr && a->expr->expr_type == EXPR_NULL
+--- a/gcc/fortran/intrinsic.c	2015-02-01 01:29:54.000000000 +0100
++++ b/gcc/fortran/intrinsic.c	2016-02-16 15:44:29.777760075 +0100
+@@ -3128,6 +3128,13 @@
+ 	      GFC_STD_F95, gfc_check_cpu_time, NULL, gfc_resolve_cpu_time,
+ 	      tm, BT_REAL, dr, REQUIRED, INTENT_OUT);
+ 
++  add_sym_3s ("event_query", GFC_ISYM_EVENT_QUERY, CLASS_ATOMIC,
++	      BT_UNKNOWN, 0, GFC_STD_F2008_TS,
++	      gfc_check_event_query, NULL, gfc_resolve_event_query,
++	      "event", BT_INTEGER, di, REQUIRED, INTENT_IN,
++	      c, BT_INTEGER, di, OPTIONAL, INTENT_IN,
++	      stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
++
+   /* More G77 compatibility garbage.  */
+   add_sym_2s ("ctime", GFC_ISYM_CTIME, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
+ 	      gfc_check_ctime_sub, NULL, gfc_resolve_ctime_sub,
+--- a/gcc/fortran/intrinsic.h	2015-01-05 13:33:28.000000000 +0100
++++ b/gcc/fortran/intrinsic.h	2016-02-16 15:44:29.778760092 +0100
+@@ -70,6 +70,7 @@
+ bool gfc_check_dshift (gfc_expr *, gfc_expr *, gfc_expr *);
+ bool gfc_check_eoshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+ bool gfc_check_dtime_etime (gfc_expr *);
++bool gfc_check_event_query (gfc_expr *, gfc_expr *, gfc_expr *);
+ bool gfc_check_fgetputc (gfc_expr *, gfc_expr *);
+ bool gfc_check_fgetput (gfc_expr *);
+ bool gfc_check_float (gfc_expr *);
+@@ -462,6 +463,7 @@
+ void gfc_resolve_eoshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
+ 			  gfc_expr *);
+ void gfc_resolve_etime_sub (gfc_code *);
++void gfc_resolve_event_query (gfc_code *);
+ void gfc_resolve_exp (gfc_expr *, gfc_expr *);
+ void gfc_resolve_exponent (gfc_expr *, gfc_expr *);
+ void gfc_resolve_extends_type_of (gfc_expr *, gfc_expr *, gfc_expr *);
+--- a/gcc/fortran/iresolve.c	2015-01-09 21:18:42.000000000 +0100
++++ b/gcc/fortran/iresolve.c	2016-02-16 15:44:29.778760092 +0100
+@@ -2955,6 +2955,12 @@
+   c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+ }
+ 
++void
++gfc_resolve_event_query (gfc_code *c)
++{
++  const char *name = "event_query";
++  c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
++}
+ 
+ void
+ gfc_resolve_mvbits (gfc_code *c)
+--- a/gcc/fortran/iso-fortran-env.def	2015-01-05 13:33:28.000000000 +0100
++++ b/gcc/fortran/iso-fortran-env.def	2016-02-16 15:44:29.778760092 +0100
+@@ -123,6 +123,11 @@
+ NAMED_DERIVED_TYPE (ISOFORTRAN_LOCK_TYPE, "lock_type", \
+               get_int_kind_from_node (ptr_type_node), GFC_STD_F2008)
+ 
++NAMED_DERIVED_TYPE (ISOFORTRAN_EVENT_TYPE, "event_type", \
++		    flag_coarray == GFC_FCOARRAY_LIB
++		    ?  get_int_kind_from_node (ptr_type_node)
++		    : gfc_default_integer_kind, GFC_STD_F2008_TS)
++
+ #undef NAMED_INTCST
+ #undef NAMED_KINDARRAY
+ #undef NAMED_FUNCTION
+--- a/gcc/fortran/match.c	2015-11-13 22:28:10.000000000 +0100
++++ b/gcc/fortran/match.c	2016-02-16 15:44:29.779760109 +0100
+@@ -1474,6 +1474,8 @@
+   match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE)
+   match ("end file", gfc_match_endfile, ST_END_FILE)
+   match ("error stop", gfc_match_error_stop, ST_ERROR_STOP)
++  match ("event post", gfc_match_event_post, ST_EVENT_POST)
++  match ("event wait", gfc_match_event_wait, ST_EVENT_WAIT)
+   match ("exit", gfc_match_exit, ST_EXIT)
+   match ("flush", gfc_match_flush, ST_FLUSH)
+   match ("forall", match_simple_forall, ST_FORALL)
+@@ -2758,6 +2760,202 @@
+   return gfc_match_stopcode (ST_ERROR_STOP);
+ }
+ 
++/* Match EVENT POST/WAIT statement. Syntax:
++     EVENT POST ( event-variable [, sync-stat-list] )
++     EVENT WAIT ( event-variable [, wait-spec-list] )
++   with
++      wait-spec-list  is  sync-stat-list  or until-spec
++      until-spec  is  UNTIL_COUNT = scalar-int-expr
++      sync-stat  is  STAT= or ERRMSG=.  */
++
++static match
++event_statement (gfc_statement st)
++{
++  match m;
++  gfc_expr *tmp, *eventvar, *until_count, *stat, *errmsg;
++  bool saw_until_count, saw_stat, saw_errmsg;
++
++  tmp = eventvar = until_count = stat = errmsg = NULL;
++  saw_until_count = saw_stat = saw_errmsg = false;
++
++  if (gfc_pure (NULL))
++    {
++      gfc_error ("Image control statement EVENT %s at %C in PURE procedure",
++		 st == ST_EVENT_POST ? "POST" : "WAIT");
++      return MATCH_ERROR;
++    }
++
++  gfc_unset_implicit_pure (NULL);
++
++  if (flag_coarray == GFC_FCOARRAY_NONE)
++    {
++       gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
++       return MATCH_ERROR;
++    }
++
++  if (gfc_find_state (COMP_CRITICAL))
++    {
++      gfc_error ("Image control statement EVENT %s at %C in CRITICAL block",
++		 st == ST_EVENT_POST ? "POST" : "WAIT");
++      return MATCH_ERROR;
++    }
++
++  if (gfc_find_state (COMP_DO_CONCURRENT))
++    {
++      gfc_error ("Image control statement EVENT %s at %C in DO CONCURRENT "
++		 "block", st == ST_EVENT_POST ? "POST" : "WAIT");
++      return MATCH_ERROR;
++    }
++
++  if (gfc_match_char ('(') != MATCH_YES)
++    goto syntax;
++
++  if (gfc_match ("%e", &eventvar) != MATCH_YES)
++    goto syntax;
++  m = gfc_match_char (',');
++  if (m == MATCH_ERROR)
++    goto syntax;
++  if (m == MATCH_NO)
++    {
++      m = gfc_match_char (')');
++      if (m == MATCH_YES)
++	goto done;
++      goto syntax;
++    }
++
++  for (;;)
++    {
++      m = gfc_match (" stat = %v", &tmp);
++      if (m == MATCH_ERROR)
++	goto syntax;
++      if (m == MATCH_YES)
++	{
++	  if (saw_stat)
++	    {
++	      gfc_error ("Redundant STAT tag found at %L ", &tmp->where);
++	      goto cleanup;
++	    }
++	  stat = tmp;
++	  saw_stat = true;
++
++	  m = gfc_match_char (',');
++	  if (m == MATCH_YES)
++	    continue;
++
++	  tmp = NULL;
++	  break;
++	}
++
++      m = gfc_match (" errmsg = %v", &tmp);
++      if (m == MATCH_ERROR)
++	goto syntax;
++      if (m == MATCH_YES)
++	{
++	  if (saw_errmsg)
++	    {
++	      gfc_error ("Redundant ERRMSG tag found at %L ", &tmp->where);
++	      goto cleanup;
++	    }
++	  errmsg = tmp;
++	  saw_errmsg = true;
++
++	  m = gfc_match_char (',');
++	  if (m == MATCH_YES)
++	    continue;
++
++	  tmp = NULL;
++	  break;
++	}
++
++      m = gfc_match (" until_count = %e", &tmp);
++      if (m == MATCH_ERROR || st == ST_EVENT_POST)
++	goto syntax;
++      if (m == MATCH_YES)
++	{
++	  if (saw_until_count)
++	    {
++	      gfc_error ("Redundant UNTIL_COUNT tag found at %L ",
++			 &tmp->where);
++	      goto cleanup;
++	    }
++	  until_count = tmp;
++	  saw_until_count = true;
++
++	  m = gfc_match_char (',');
++	  if (m == MATCH_YES)
++	    continue;
++
++	  tmp = NULL;
++	  break;
++	}
++
++      break;
++    }
++
++  if (m == MATCH_ERROR)
++    goto syntax;
++
++  if (gfc_match (" )%t") != MATCH_YES)
++    goto syntax;
++
++done:
++  switch (st)
++    {
++    case ST_EVENT_POST:
++      new_st.op = EXEC_EVENT_POST;
++      break;
++    case ST_EVENT_WAIT:
++      new_st.op = EXEC_EVENT_WAIT;
++      break;
++    default:
++      gcc_unreachable ();
++    }
++
++  new_st.expr1 = eventvar;
++  new_st.expr2 = stat;
++  new_st.expr3 = errmsg;
++  new_st.expr4 = until_count;
++
++  return MATCH_YES;
++
++syntax:
++  gfc_syntax_error (st);
++
++cleanup:
++  if (until_count != tmp)
++    gfc_free_expr (until_count);
++  if (errmsg != tmp)
++    gfc_free_expr (errmsg);
++  if (stat != tmp)
++    gfc_free_expr (stat);
++
++  gfc_free_expr (tmp);
++  gfc_free_expr (eventvar);
++
++  return MATCH_ERROR;
++
++}
++
++
++match
++gfc_match_event_post (void)
++{
++  if (!gfc_notify_std (GFC_STD_F2008_TS, "EVENT POST statement at %C"))
++    return MATCH_ERROR;
++
++  return event_statement (ST_EVENT_POST);
++}
++
++
++match
++gfc_match_event_wait (void)
++{
++  if (!gfc_notify_std (GFC_STD_F2008_TS, "EVENT WAIT statement at %C"))
++    return MATCH_ERROR;
++
++  return event_statement (ST_EVENT_WAIT);
++}
++
+ 
+ /* Match LOCK/UNLOCK statement. Syntax:
+      LOCK ( lock-variable [ , lock-stat-list ] )
+--- a/gcc/fortran/match.h	2015-01-15 21:11:12.000000000 +0100
++++ b/gcc/fortran/match.h	2016-02-16 15:44:29.779760109 +0100
+@@ -69,6 +69,8 @@
+ match gfc_match_if (gfc_statement *);
+ match gfc_match_else (void);
+ match gfc_match_elseif (void);
++match gfc_match_event_post (void);
++match gfc_match_event_wait (void);
+ match gfc_match_critical (void);
+ match gfc_match_block (void);
+ match gfc_match_associate (void);
+--- a/gcc/fortran/module.c	2015-06-05 22:40:35.000000000 +0200
++++ b/gcc/fortran/module.c	2016-02-16 15:44:29.780760126 +0100
+@@ -1889,7 +1889,7 @@
+   AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
+   AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE,
+   AB_ALLOC_COMP, AB_POINTER_COMP, AB_PROC_POINTER_COMP, AB_PRIVATE_COMP,
+-  AB_VALUE, AB_VOLATILE, AB_PROTECTED, AB_LOCK_COMP,
++  AB_VALUE, AB_VOLATILE, AB_PROTECTED, AB_LOCK_COMP, AB_EVENT_COMP,
+   AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT, AB_ZERO_COMP,
+   AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER, AB_ASYNCHRONOUS, AB_CODIMENSION,
+   AB_COARRAY_COMP, AB_VTYPE, AB_VTAB, AB_CONTIGUOUS, AB_CLASS_POINTER,
+@@ -1935,6 +1935,7 @@
+     minit ("ALLOC_COMP", AB_ALLOC_COMP),
+     minit ("COARRAY_COMP", AB_COARRAY_COMP),
+     minit ("LOCK_COMP", AB_LOCK_COMP),
++    minit ("EVENT_COMP", AB_EVENT_COMP),
+     minit ("POINTER_COMP", AB_POINTER_COMP),
+     minit ("PROC_POINTER_COMP", AB_PROC_POINTER_COMP),
+     minit ("PRIVATE_COMP", AB_PRIVATE_COMP),
+@@ -2117,6 +2118,8 @@
+ 	MIO_NAME (ab_attribute) (AB_COARRAY_COMP, attr_bits);
+       if (attr->lock_comp)
+ 	MIO_NAME (ab_attribute) (AB_LOCK_COMP, attr_bits);
++      if (attr->event_comp)
++	MIO_NAME (ab_attribute) (AB_EVENT_COMP, attr_bits);
+       if (attr->zero_comp)
+ 	MIO_NAME (ab_attribute) (AB_ZERO_COMP, attr_bits);
+       if (attr->is_class)
+@@ -2269,6 +2272,9 @@
+ 	    case AB_LOCK_COMP:
+ 	      attr->lock_comp = 1;
+ 	      break;
++	    case AB_EVENT_COMP:
++	      attr->event_comp = 1;
++	      break;
+ 	    case AB_POINTER_COMP:
+ 	      attr->pointer_comp = 1;
+ 	      break;
+--- a/gcc/fortran/parse.c	2015-09-26 00:45:27.000000000 +0200
++++ b/gcc/fortran/parse.c	2016-02-16 15:44:29.780760126 +0100
+@@ -457,6 +457,8 @@
+       match ("entry% ", gfc_match_entry, ST_ENTRY);
+       match ("equivalence", gfc_match_equivalence, ST_EQUIVALENCE);
+       match ("external", gfc_match_external, ST_ATTR_DECL);
++      match ("event post", gfc_match_event_post, ST_EVENT_POST);
++      match ("event wait", gfc_match_event_wait, ST_EVENT_WAIT);
+       break;
+ 
+     case 'f':
+@@ -1323,6 +1325,7 @@
+   case ST_OMP_CANCEL: case ST_OMP_CANCELLATION_POINT: \
+   case ST_OMP_TARGET_UPDATE: case ST_ERROR_STOP: case ST_SYNC_ALL: \
+   case ST_SYNC_IMAGES: case ST_SYNC_MEMORY: case ST_LOCK: case ST_UNLOCK: \
++  case ST_EVENT_POST: case ST_EVENT_WAIT: \
+   case ST_OACC_UPDATE: case ST_OACC_WAIT: case ST_OACC_CACHE: \
+   case ST_OACC_ENTER_DATA: case ST_OACC_EXIT_DATA
+ 
+@@ -1628,6 +1631,12 @@
+     case ST_ELSEWHERE:
+       p = "ELSEWHERE";
+       break;
++    case ST_EVENT_POST:
++      p = "EVENT POST";
++      break;
++    case ST_EVENT_WAIT:
++      p = "EVENT WAIT";
++      break;
+     case ST_END_ASSOCIATE:
+       p = "END ASSOCIATE";
+       break;
+@@ -2608,7 +2617,7 @@
+   gfc_statement st;
+   gfc_state_data s;
+   gfc_symbol *sym;
+-  gfc_component *c, *lock_comp = NULL;
++  gfc_component *c, *lock_comp = NULL, *event_comp = NULL;
+ 
+   accept_statement (ST_DERIVED_DECL);
+   push_state (&s, COMP_DERIVED, gfc_new_block);
+@@ -2716,8 +2725,8 @@
+   sym = gfc_current_block ();
+   for (c = sym->components; c; c = c->next)
+     {
+-      bool coarray, lock_type, allocatable, pointer;
+-      coarray = lock_type = allocatable = pointer = false;
++      bool coarray, lock_type, event_type, allocatable, pointer;
++      coarray = lock_type = event_type = allocatable = pointer = false;
+ 
+       /* Look for allocatable components.  */
+       if (c->attr.allocatable
+@@ -2779,6 +2788,23 @@
+ 	  sym->attr.lock_comp = 1;
+ 	}
+ 
++      /* Looking for event_type components.  */
++      if ((c->ts.type == BT_DERIVED
++	      && c->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++	      && c->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
++	  || (c->ts.type == BT_CLASS && c->attr.class_ok
++	      && CLASS_DATA (c)->ts.u.derived->from_intmod
++		 == INTMOD_ISO_FORTRAN_ENV
++	      && CLASS_DATA (c)->ts.u.derived->intmod_sym_id
++		 == ISOFORTRAN_EVENT_TYPE)
++	  || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.event_comp
++	      && !allocatable && !pointer))
++	{
++	  event_type = 1;
++	  event_comp = c;
++	  sym->attr.event_comp = 1;
++	}
++
+       /* Check for F2008, C1302 - and recall that pointers may not be coarrays
+ 	 (5.3.14) and that subobjects of coarray are coarray themselves (2.4.7),
+ 	 unless there are nondirect [allocatable or pointer] components
+@@ -2819,6 +2845,43 @@
+ 		   "coarray subcomponent)", lock_comp->name, &lock_comp->loc,
+ 		   sym->name, c->name, &c->loc);
+ 
++      /* Similarly for EVENT TYPE.  */
++
++      if (pointer && !coarray && event_type)
++	gfc_error ("Component %s at %L of type EVENT_TYPE must have a "
++		   "codimension or be a subcomponent of a coarray, "
++		   "which is not possible as the component has the "
++		   "pointer attribute", c->name, &c->loc);
++      else if (pointer && !coarray && c->ts.type == BT_DERIVED
++	       && c->ts.u.derived->attr.event_comp)
++	gfc_error ("Pointer component %s at %L has a noncoarray subcomponent "
++		   "of type EVENT_TYPE, which must have a codimension or be a "
++		   "subcomponent of a coarray", c->name, &c->loc);
++
++      if (event_type && allocatable && !coarray)
++	gfc_error ("Allocatable component %s at %L of type EVENT_TYPE must have "
++		   "a codimension", c->name, &c->loc);
++      else if (event_type && allocatable && c->ts.type == BT_DERIVED
++	       && c->ts.u.derived->attr.event_comp)
++	gfc_error ("Allocatable component %s at %L must have a codimension as "
++		   "it has a noncoarray subcomponent of type EVENT_TYPE",
++		   c->name, &c->loc);
++
++      if (sym->attr.coarray_comp && !coarray && event_type)
++	gfc_error ("Noncoarray component %s at %L of type EVENT_TYPE or with "
++		   "subcomponent of type EVENT_TYPE must have a codimension or "
++		   "be a subcomponent of a coarray. (Variables of type %s may "
++		   "not have a codimension as already a coarray "
++		   "subcomponent exists)", c->name, &c->loc, sym->name);
++
++      if (sym->attr.event_comp && coarray && !event_type)
++	gfc_error ("Noncoarray component %s at %L of type EVENT_TYPE or with "
++		   "subcomponent of type EVENT_TYPE must have a codimension or "
++		   "be a subcomponent of a coarray. (Variables of type %s may "
++		   "not have a codimension as %s at %L has a codimension or a "
++		   "coarray subcomponent)", event_comp->name, &event_comp->loc,
++		   sym->name, c->name, &c->loc);
++
+       /* Look for private components.  */
+       if (sym->component_access == ACCESS_PRIVATE
+ 	  || c->attr.access == ACCESS_PRIVATE
+--- a/gcc/fortran/primary.c	2015-10-26 18:25:03.000000000 +0100
++++ b/gcc/fortran/primary.c	2016-02-16 15:30:54.152087966 +0100
+@@ -2142,7 +2142,7 @@
+ symbol_attribute
+ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
+ {
+-  int dimension, codimension, pointer, allocatable, target, n;
++  int dimension, codimension, pointer, allocatable, target;
+   symbol_attribute attr;
+   gfc_ref *ref;
+   gfc_symbol *sym;
+@@ -2201,22 +2201,9 @@
+ 	  case AR_UNKNOWN:
+ 	    /* If any of start, end or stride is not integer, there will
+ 	       already have been an error issued.  */
+-	    for (n = 0; n < ref->u.ar.as->rank; n++)
+-	      {
+-		int errors;
+-		gfc_get_errors (NULL, &errors);
+-		if (((ref->u.ar.start[n]
+-		      && ref->u.ar.start[n]->ts.type == BT_UNKNOWN)
+-		     ||
+-		     (ref->u.ar.end[n]
+-		      && ref->u.ar.end[n]->ts.type == BT_UNKNOWN)
+-		     ||
+-		     (ref->u.ar.stride[n]
+-		      && ref->u.ar.stride[n]->ts.type == BT_UNKNOWN))
+-		    && errors > 0)
+-		  break;
+-	      }
+-	    if (n == ref->u.ar.as->rank)
++	    int errors;
++	    gfc_get_errors (NULL, &errors);
++	    if (errors == 0)
+ 	      gfc_internal_error ("gfc_variable_attr(): Bad array reference");
+ 	  }
+ 
+--- a/gcc/fortran/resolve.c	2015-10-20 02:45:48.000000000 +0200
++++ b/gcc/fortran/resolve.c	2016-02-16 15:44:29.782760161 +0100
+@@ -1,5 +1,5 @@
+ /* Perform type resolution on the various structures.
+-   Copyright (C) 2001-2015 Free Software Foundation, Inc.
++   Copyright (C) 2001-2016 Free Software Foundation, Inc.
+    Contributed by Andy Vaught
+ 
+ This file is part of GCC.
+@@ -6977,6 +6977,21 @@
+ 		      &code->expr3->where, &e->where);
+ 	  goto failure;
+ 	}
++
++      /* Check TS18508, C702/C703.  */
++      if (code->expr3->ts.type == BT_DERIVED
++	  && ((codimension && gfc_expr_attr (code->expr3).event_comp)
++	      || (code->expr3->ts.u.derived->from_intmod
++		     == INTMOD_ISO_FORTRAN_ENV
++		  && code->expr3->ts.u.derived->intmod_sym_id
++		     == ISOFORTRAN_EVENT_TYPE)))
++	{
++	  gfc_error ("The source-expr at %L shall neither be of type "
++		     "EVENT_TYPE nor have a EVENT_TYPE component if "
++		      "allocate-object at %L is a coarray",
++		      &code->expr3->where, &e->where);
++	  goto failure;
++	}
+     }
+ 
+   /* Check F08:C629.  */
+@@ -7028,6 +7043,13 @@
+ 	 no SOURCE exists by setting expr3.  */
+       code->expr3 = gfc_default_initializer (&code->ext.alloc.ts);
+     }
++  else if (flag_coarray != GFC_FCOARRAY_LIB && e->ts.type == BT_DERIVED
++	   && e->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++	   && e->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
++    {
++      /* We have to zero initialize the integer variable.  */
++      code->expr3 = gfc_get_int_expr (gfc_default_integer_kind, &e->where, 0);
++    }
+   else if (!code->expr3)
+     {
+       /* Set up default initializer if needed.  */
+@@ -8494,7 +8516,7 @@
+ 	  return;
+ 	}
+     }
+-   
++
+   if (exp->expr_type == EXPR_STRUCTURE)
+     return;
+ 
+@@ -8545,21 +8567,40 @@
+ 
+ 
+ static void
+-resolve_lock_unlock (gfc_code *code)
++resolve_lock_unlock_event (gfc_code *code)
+ {
+   if (code->expr1->expr_type == EXPR_FUNCTION
+       && code->expr1->value.function.isym
+       && code->expr1->value.function.isym->id == GFC_ISYM_CAF_GET)
+     remove_caf_get_intrinsic (code->expr1);
+ 
+-  if (code->expr1->ts.type != BT_DERIVED
+-      || code->expr1->expr_type != EXPR_VARIABLE
+-      || code->expr1->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
+-      || code->expr1->ts.u.derived->intmod_sym_id != ISOFORTRAN_LOCK_TYPE
+-      || code->expr1->rank != 0
+-      || (!gfc_is_coarray (code->expr1) && !gfc_is_coindexed (code->expr1)))
++  if ((code->op == EXEC_LOCK || code->op == EXEC_UNLOCK)
++      && (code->expr1->ts.type != BT_DERIVED
++	  || code->expr1->expr_type != EXPR_VARIABLE
++	  || code->expr1->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
++	  || code->expr1->ts.u.derived->intmod_sym_id != ISOFORTRAN_LOCK_TYPE
++	  || code->expr1->rank != 0
++	  || (!gfc_is_coarray (code->expr1) &&
++	      !gfc_is_coindexed (code->expr1))))
+     gfc_error ("Lock variable at %L must be a scalar of type LOCK_TYPE",
+ 	       &code->expr1->where);
++  else if ((code->op == EXEC_EVENT_POST || code->op == EXEC_EVENT_WAIT)
++	   && (code->expr1->ts.type != BT_DERIVED
++	       || code->expr1->expr_type != EXPR_VARIABLE
++	       || code->expr1->ts.u.derived->from_intmod
++		  != INTMOD_ISO_FORTRAN_ENV
++	       || code->expr1->ts.u.derived->intmod_sym_id
++		  != ISOFORTRAN_EVENT_TYPE
++	       || code->expr1->rank != 0))
++    gfc_error ("Event variable at %L must be a scalar of type EVENT_TYPE",
++	       &code->expr1->where);
++  else if (code->op == EXEC_EVENT_POST && !gfc_is_coarray (code->expr1)
++	   && !gfc_is_coindexed (code->expr1))
++    gfc_error ("Event variable argument at %L must be a coarray or coindexed",
++	       &code->expr1->where);
++  else if (code->op == EXEC_EVENT_WAIT && !gfc_is_coarray (code->expr1))
++    gfc_error ("Event variable argument at %L must be a coarray but not "
++	       "coindexed", &code->expr1->where);
+ 
+   /* Check STAT.  */
+   if (code->expr2
+@@ -8585,17 +8626,23 @@
+ 				    _("ERRMSG variable")))
+     return;
+ 
+-  /* Check ACQUIRED_LOCK.  */
+-  if (code->expr4
++  /* Check for LOCK the ACQUIRED_LOCK.  */
++  if (code->op != EXEC_EVENT_WAIT && code->expr4
+       && (code->expr4->ts.type != BT_LOGICAL || code->expr4->rank != 0
+ 	  || code->expr4->expr_type != EXPR_VARIABLE))
+     gfc_error ("ACQUIRED_LOCK= argument at %L must be a scalar LOGICAL "
+ 	       "variable", &code->expr4->where);
+ 
+-  if (code->expr4
++  if (code->op != EXEC_EVENT_WAIT && code->expr4
+       && !gfc_check_vardef_context (code->expr4, false, false, false,
+ 				    _("ACQUIRED_LOCK variable")))
+     return;
++
++  /* Check for EVENT WAIT the UNTIL_COUNT.  */
++  if (code->op == EXEC_EVENT_WAIT && code->expr4
++      && (code->expr4->ts.type != BT_INTEGER || code->expr4->rank != 0))
++    gfc_error ("UNTIL_COUNT= argument at %L must be a scalar INTEGER "
++	       "expression", &code->expr4->where);
+ }
+ 
+ 
+@@ -8643,6 +8690,7 @@
+   symtree->n.sym->as->cotype = AS_EXPLICIT;
+   symtree->n.sym->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
+ 						   NULL, 1);
++  gfc_commit_symbols();
+ }
+ 
+ 
+@@ -9992,6 +10040,50 @@
+ }
+ 
+ 
++/* Deferred character length assignments from an operator expression
++   require a temporary because the character length of the lhs can
++   change in the course of the assignment.  */
++
++static bool
++deferred_op_assign (gfc_code **code, gfc_namespace *ns)
++{
++  gfc_expr *tmp_expr;
++  gfc_code *this_code;
++
++  if (!((*code)->expr1->ts.type == BT_CHARACTER
++	 && (*code)->expr1->ts.deferred && (*code)->expr1->rank
++	 && (*code)->expr2->expr_type == EXPR_OP))
++    return false;
++
++  if (!gfc_check_dependency ((*code)->expr1, (*code)->expr2, 1))
++    return false;
++
++  tmp_expr = get_temp_from_expr ((*code)->expr1, ns);
++  tmp_expr->where = (*code)->loc;
++
++  /* A new charlen is required to ensure that the variable string
++     length is different to that of the original lhs.  */
++  tmp_expr->ts.u.cl = gfc_get_charlen();
++  tmp_expr->symtree->n.sym->ts.u.cl = tmp_expr->ts.u.cl;
++  tmp_expr->ts.u.cl->next = (*code)->expr2->ts.u.cl->next;
++  (*code)->expr2->ts.u.cl->next = tmp_expr->ts.u.cl;
++
++  tmp_expr->symtree->n.sym->ts.deferred = 1;
++
++  this_code = build_assignment (EXEC_ASSIGN,
++				(*code)->expr1,
++				gfc_copy_expr (tmp_expr),
++				NULL, NULL, (*code)->loc);
++
++  (*code)->expr1 = tmp_expr;
++
++  this_code->next = (*code)->next;
++  (*code)->next = this_code;
++
++  return true;
++}
++
++
+ /* Given a block of code, recursively resolve everything pointed to by this
+    code block.  */
+ 
+@@ -10128,7 +10220,9 @@
+ 
+ 	case EXEC_LOCK:
+ 	case EXEC_UNLOCK:
+-	  resolve_lock_unlock (code);
++	case EXEC_EVENT_POST:
++	case EXEC_EVENT_WAIT:
++	  resolve_lock_unlock_event (code);
+ 	  break;
+ 
+ 	case EXEC_ENTRY:
+@@ -10189,6 +10283,11 @@
+ 		goto call;
+ 	    }
+ 
++	  /* Check for dependencies in deferred character length array
++	     assignments and generate a temporary, if necessary.  */
++	  if (code->op == EXEC_ASSIGN && deferred_op_assign (&code, ns))
++	    break;
++
+ 	  /* F03 7.4.1.3 for non-allocatable, non-pointer components.  */
+ 	  if (code->op != EXEC_CALL && code->expr1->ts.type == BT_DERIVED
+ 	      && code->expr1->ts.u.derived->attr.defined_assign_comp)
+@@ -10561,7 +10660,7 @@
+       sym->binding_label = NULL;
+ 
+     }
+-  else if (sym->attr.flavor == FL_VARIABLE && module 
++  else if (sym->attr.flavor == FL_VARIABLE && module
+ 	   && (strcmp (module, gsym->mod_name) != 0
+ 	       || strcmp (sym->name, gsym->sym_name) != 0))
+     {
+@@ -13613,6 +13712,19 @@
+       return;
+     }
+ 
++  /* TS18508, C702/C703.  */
++  if (sym->ts.type == BT_DERIVED
++      && ((sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++	   && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
++	  || sym->ts.u.derived->attr.event_comp)
++      && !sym->attr.codimension && !sym->ts.u.derived->attr.coarray_comp)
++    {
++      gfc_error ("Variable %s at %L of type EVENT_TYPE or with subcomponent of "
++		 "type LOCK_TYPE must be a coarray", sym->name,
++		 &sym->declared_at);
++      return;
++    }
++
+   /* An assumed-size array with INTENT(OUT) shall not be of a type for which
+      default initialization is defined (5.1.2.4.4).  */
+   if (sym->ts.type == BT_DERIVED
+@@ -13641,6 +13753,15 @@
+ 		 "INTENT(OUT)", sym->name, &sym->declared_at);
+       return;
+     }
++
++  /* TS18508.  */
++  if (sym->ts.type == BT_DERIVED && sym->attr.dummy
++      && sym->attr.intent == INTENT_OUT && sym->attr.event_comp)
++    {
++      gfc_error ("Dummy argument %qs at %L of EVENT_TYPE shall not be "
++		 "INTENT(OUT)", sym->name, &sym->declared_at);
++      return;
++    }
+ 
+   /* F2008, C525.  */
+   if ((((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp)
+--- a/gcc/fortran/st.c	2015-01-15 21:11:12.000000000 +0100
++++ b/gcc/fortran/st.c	2016-02-16 15:44:29.782760161 +0100
+@@ -118,6 +118,8 @@
+     case EXEC_SYNC_MEMORY:
+     case EXEC_LOCK:
+     case EXEC_UNLOCK:
++    case EXEC_EVENT_POST:
++    case EXEC_EVENT_WAIT:
+       break;
+ 
+     case EXEC_BLOCK:
+--- a/gcc/fortran/symbol.c	2015-05-19 19:01:25.000000000 +0200
++++ b/gcc/fortran/symbol.c	2016-02-16 15:34:33.988269947 +0100
+@@ -3121,49 +3121,49 @@
+ 
+   FOR_EACH_VEC_ELT (latest_undo_chgset->syms, i, p)
+     {
+-      if (p->gfc_new)
++      /* Symbol was new. Or was old and just put in common */
++      if ((p->gfc_new
++	   || (p->attr.in_common && !p->old_symbol->attr.in_common ))
++	  && p->attr.in_common && p->common_block && p->common_block->head)
+ 	{
+-	  /* Symbol was new.  */
+-	  if (p->attr.in_common && p->common_block && p->common_block->head)
+-	    {
+-	      /* If the symbol was added to any common block, it
+-		 needs to be removed to stop the resolver looking
+-		 for a (possibly) dead symbol.  */
++	  /* If the symbol was added to any common block, it
++	     needs to be removed to stop the resolver looking
++	     for a (possibly) dead symbol.  */
+ 
+-	      if (p->common_block->head == p && !p->common_next)
++	  if (p->common_block->head == p && !p->common_next)
++	    {
++	      gfc_symtree st, *st0;
++	      st0 = find_common_symtree (p->ns->common_root,
++					 p->common_block);
++	      if (st0)
+ 		{
+-		  gfc_symtree st, *st0;
+-		  st0 = find_common_symtree (p->ns->common_root,
+-					     p->common_block);
+-		  if (st0)
+-		    {
+-		      st.name = st0->name;
+-		      gfc_delete_bbt (&p->ns->common_root, &st, compare_symtree);
+-		      free (st0);
+-		    }
++		  st.name = st0->name;
++		  gfc_delete_bbt (&p->ns->common_root, &st, compare_symtree);
++		  free (st0);
+ 		}
++	    }
+ 
+-	      if (p->common_block->head == p)
+-	        p->common_block->head = p->common_next;
+-	      else
+-		{
+-		  gfc_symbol *cparent, *csym;
+-
+-		  cparent = p->common_block->head;
+-		  csym = cparent->common_next;
+-
+-		  while (csym != p)
+-		    {
+-		      cparent = csym;
+-		      csym = csym->common_next;
+-		    }
++	  if (p->common_block->head == p)
++	    p->common_block->head = p->common_next;
++	  else
++	    {
++	      gfc_symbol *cparent, *csym;
+ 
+-		  gcc_assert(cparent->common_next == p);
++	      cparent = p->common_block->head;
++	      csym = cparent->common_next;
+ 
+-		  cparent->common_next = csym->common_next;
++	      while (csym != p)
++		{
++		  cparent = csym;
++		  csym = csym->common_next;
+ 		}
+-	    }
+ 
++	      gcc_assert(cparent->common_next == p);
++	      cparent->common_next = csym->common_next;
++	    }
++	}
++      if (p->gfc_new)
++	{
+ 	  /* The derived type is saved in the symtree with the first
+ 	     letter capitalized; the all lower-case version to the
+ 	     derived type contains its associated generic function.  */
+--- a/gcc/fortran/trans-array.c	2015-11-27 15:08:23.000000000 +0100
++++ b/gcc/fortran/trans-array.c	2016-02-16 15:42:04.613303608 +0100
+@@ -1,5 +1,5 @@
+ /* Array translation routines
+-   Copyright (C) 2002-2015 Free Software Foundation, Inc.
++   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+    Contributed by Paul Brook <paul at nowt.org>
+    and Steven Bosscher <s.bosscher at student.tudelft.nl>
+ 
+@@ -3112,7 +3112,8 @@
+     index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+ 			     index, info->offset);
+ 
+-  if (expr && is_subref_array (expr))
++  if (expr && (is_subref_array (expr)
++	       || (expr->ts.deferred && expr->expr_type == EXPR_VARIABLE)))
+     decl = expr->symtree->n.sym->backend_decl;
+ 
+   tmp = build_fold_indirect_ref_loc (input_location, info->data);
+@@ -3532,7 +3533,8 @@
+   tree init;
+   tree incr;
+ 
+-  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
++  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS
++		      | OMPWS_SCALARIZER_BODY))
+       == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
+       && n == loop->dimen - 1)
+     {
+@@ -4409,7 +4411,7 @@
+ 	  if (!nDepend && dest_expr->rank > 0
+ 	      && dest_expr->ts.type == BT_CHARACTER
+ 	      && ss_expr->expr_type == EXPR_VARIABLE)
+-	    
++
+ 	    nDepend = gfc_check_dependency (dest_expr, ss_expr, false);
+ 
+ 	  continue;
+@@ -6945,7 +6947,7 @@
+ 				    gfc_array_index_type,
+ 				    stride, info->stride[n]);
+ 
+-	  if (se->direct_byref
++	  if ((se->direct_byref || se->use_offset)
+ 	      && ((info->ref && info->ref->u.ar.type != AR_FULL)
+ 		  || (expr->expr_type == EXPR_ARRAY && se->use_offset)))
+ 	    {
+@@ -7191,6 +7193,17 @@
+   if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp)
+     {
+       gfc_conv_expr_descriptor (se, expr);
++      /* Deallocate the allocatable components of structures that are
++	 not variable.  */
++      if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
++	   && expr->ts.u.derived->attr.alloc_comp
++	   && expr->expr_type != EXPR_VARIABLE)
++	{
++	  tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se->expr, expr->rank);
++
++	  /* The components shall be deallocated before their containing entity.  */
++	  gfc_prepend_expr_to_block (&se->post, tmp);
++	}
+       if (expr->ts.type == BT_CHARACTER)
+ 	se->string_length = expr->ts.u.cl->backend_decl;
+       if (size)
+@@ -7226,10 +7239,11 @@
+     }
+ 
+   /* Deallocate the allocatable components of structures that are
+-     not variable.  */
+-  if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
+-	&& expr->ts.u.derived->attr.alloc_comp
+-	&& expr->expr_type != EXPR_VARIABLE)
++     not variable, for descriptorless arguments.
++     Arguments with a descriptor are handled in gfc_conv_procedure_call.  */
++  if (g77 && (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
++	  && expr->ts.u.derived->attr.alloc_comp
++	  && expr->expr_type != EXPR_VARIABLE)
+     {
+       tmp = build_fold_indirect_ref_loc (input_location, se->expr);
+       tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
+@@ -8269,6 +8283,75 @@
+ }
+ 
+ 
++static tree
++concat_str_length (gfc_expr* expr)
++{
++  tree type;
++  tree len1;
++  tree len2;
++  gfc_se se;
++
++  type = gfc_typenode_for_spec (&expr->value.op.op1->ts);
++  len1 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
++  if (len1 == NULL_TREE)
++    {
++      if (expr->value.op.op1->expr_type == EXPR_OP)
++	len1 = concat_str_length (expr->value.op.op1);
++      else if (expr->value.op.op1->expr_type == EXPR_CONSTANT)
++	len1 = build_int_cst (gfc_charlen_type_node,
++			expr->value.op.op1->value.character.length);
++      else if (expr->value.op.op1->ts.u.cl->length)
++	{
++	  gfc_init_se (&se, NULL);
++	  gfc_conv_expr (&se, expr->value.op.op1->ts.u.cl->length);
++	  len1 = se.expr;
++	}
++      else
++	{
++	  /* Last resort!  */
++	  gfc_init_se (&se, NULL);
++	  se.want_pointer = 1;
++	  se.descriptor_only = 1;
++	  gfc_conv_expr (&se, expr->value.op.op1);
++	  len1 = se.string_length;
++	}
++    }
++
++  type = gfc_typenode_for_spec (&expr->value.op.op2->ts);
++  len2 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
++  if (len2 == NULL_TREE)
++    {
++      if (expr->value.op.op2->expr_type == EXPR_OP)
++	len2 = concat_str_length (expr->value.op.op2);
++      else if (expr->value.op.op2->expr_type == EXPR_CONSTANT)
++	len2 = build_int_cst (gfc_charlen_type_node,
++			expr->value.op.op2->value.character.length);
++      else if (expr->value.op.op2->ts.u.cl->length)
++	{
++	  gfc_init_se (&se, NULL);
++	  gfc_conv_expr (&se, expr->value.op.op2->ts.u.cl->length);
++	  len2 = se.expr;
++	}
++      else
++	{
++	  /* Last resort!  */
++	  gfc_init_se (&se, NULL);
++	  se.want_pointer = 1;
++	  se.descriptor_only = 1;
++	  gfc_conv_expr (&se, expr->value.op.op2);
++	  len2 = se.string_length;
++	}
++    }
++
++  gcc_assert(len1 && len2);
++  len1 = fold_convert (gfc_charlen_type_node, len1);
++  len2 = fold_convert (gfc_charlen_type_node, len2);
++
++  return fold_build2_loc (input_location, PLUS_EXPR,
++			  gfc_charlen_type_node, len1, len2);
++}
++
++
+ /* Allocate the lhs of an assignment to an allocatable array, otherwise
+    reallocate it.  */
+ 
+@@ -8366,6 +8449,12 @@
+   /* Allocate if data is NULL.  */
+   cond_null = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
+ 			 array1, build_int_cst (TREE_TYPE (array1), 0));
++
++  if (expr1->ts.deferred)
++    cond_null = gfc_evaluate_now (boolean_true_node, &fblock);
++  else
++    cond_null= gfc_evaluate_now (cond_null, &fblock);
++
+   tmp = build3_v (COND_EXPR, cond_null,
+ 		  build1_v (GOTO_EXPR, jump_label1),
+ 		  build_empty_stmt (input_location));
+@@ -8454,7 +8543,13 @@
+ 
+   cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+ 			  size1, size2);
+-  neq_size = gfc_evaluate_now (cond, &fblock);
++
++  /* If the lhs is deferred length, assume that the element size
++     changes and force a reallocation.  */
++  if (expr1->ts.deferred)
++    neq_size = gfc_evaluate_now (boolean_true_node, &fblock);
++  else
++    neq_size = gfc_evaluate_now (cond, &fblock);
+ 
+   /* Deallocation of allocatable components will have to occur on
+      reallocation.  Fix the old descriptor now.  */
+@@ -8559,6 +8654,12 @@
+       else
+ 	{
+ 	  tmp = expr2->ts.u.cl->backend_decl;
++	  if (!tmp && expr2->expr_type == EXPR_OP
++	      && expr2->value.op.op == INTRINSIC_CONCAT)
++	    {
++	      tmp = concat_str_length (expr2);
++	      expr2->ts.u.cl->backend_decl = gfc_evaluate_now (tmp, &fblock);
++	    }
+ 	  tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);
+ 	}
+ 
+@@ -8586,6 +8687,22 @@
+ 			   size2, size_one_node);
+   size2 = gfc_evaluate_now (size2, &fblock);
+ 
++  /* For deferred character length, the 'size' field of the dtype might
++     have changed so set the dtype.  */
++  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
++      && expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
++    {
++      tree type;
++      tmp = gfc_conv_descriptor_dtype (desc);
++      if (expr2->ts.u.cl->backend_decl)
++	type = gfc_typenode_for_spec (&expr2->ts);
++      else
++	type = gfc_typenode_for_spec (&expr1->ts);
++
++      gfc_add_modify (&fblock, tmp,
++		      gfc_get_dtype_rank_type (expr1->rank,type));
++    }
++
+   /* Realloc expression.  Note that the scalarizer uses desc.data
+      in the array reference - (*desc.data)[<element>].  */
+   gfc_init_block (&realloc_block);
+@@ -8628,8 +8745,16 @@
+ 			     1, size2);
+   gfc_conv_descriptor_data_set (&alloc_block,
+ 				desc, tmp);
+-  tmp = gfc_conv_descriptor_dtype (desc);
+-  gfc_add_modify (&alloc_block, tmp, gfc_get_dtype (TREE_TYPE (desc)));
++
++  /* We already set the dtype in the case of deferred character
++     length arrays.  */
++  if (!(GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
++        && expr1->ts.type == BT_CHARACTER && expr1->ts.deferred))
++    {
++      tmp = gfc_conv_descriptor_dtype (desc);
++      gfc_add_modify (&alloc_block, tmp, gfc_get_dtype (TREE_TYPE (desc)));
++    }
++
+   if ((expr1->ts.type == BT_DERIVED)
+ 	&& expr1->ts.u.derived->attr.alloc_comp)
+     {
+--- a/gcc/fortran/trans.c	2015-04-10 14:03:35.000000000 +0200
++++ b/gcc/fortran/trans.c	2016-02-16 15:44:29.788760264 +0100
+@@ -1,5 +1,5 @@
+ /* Code translation -- generate GCC trees from gfc_code.
+-   Copyright (C) 2002-2015 Free Software Foundation, Inc.
++   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+    Contributed by Paul Brook
+ 
+ This file is part of GCC.
+@@ -344,6 +344,18 @@
+ 
+   type = TREE_TYPE (type);
+ 
++  /* Use pointer arithmetic for deferred character length array
++     references.  */
++  if (type && TREE_CODE (type) == ARRAY_TYPE
++      && TYPE_MAXVAL (TYPE_DOMAIN (type)) != NULL_TREE
++      && TREE_CODE (TYPE_MAXVAL (TYPE_DOMAIN (type))) == VAR_DECL
++      && decl
++      && DECL_CONTEXT (TYPE_MAXVAL (TYPE_DOMAIN (type)))
++					== DECL_CONTEXT (decl))
++    span = TYPE_MAXVAL (TYPE_DOMAIN (type));
++  else
++    span = NULL_TREE;
++
+   if (DECL_P (base))
+     TREE_ADDRESSABLE (base) = 1;
+ 
+@@ -358,7 +370,8 @@
+ 		 || TREE_CODE (decl) == PARM_DECL)
+ 	&& ((GFC_DECL_SUBREF_ARRAY_P (decl)
+ 	      && !integer_zerop (GFC_DECL_SPAN(decl)))
+-	   || GFC_DECL_CLASS (decl)))
++	   || GFC_DECL_CLASS (decl)
++	   || span != NULL_TREE))
+     {
+       if (GFC_DECL_CLASS (decl))
+ 	{
+@@ -377,6 +390,8 @@
+ 	}
+       else if (GFC_DECL_SUBREF_ARRAY_P (decl))
+ 	span = GFC_DECL_SPAN(decl);
++      else if (span)
++	span = fold_convert (gfc_array_index_type, span);
+       else
+ 	gcc_unreachable ();
+ 
+@@ -701,7 +716,7 @@
+ static void
+ gfc_allocate_using_lib (stmtblock_t * block, tree pointer, tree size,
+ 			tree token, tree status, tree errmsg, tree errlen,
+-			bool lock_var)
++			bool lock_var, bool event_var)
+ {
+   tree tmp, pstat;
+ 
+@@ -732,13 +747,24 @@
+ 			      build_int_cst (size_type_node, 1)),
+ 	     build_int_cst (integer_type_node,
+ 			    lock_var ? GFC_CAF_LOCK_ALLOC
+-				     : GFC_CAF_COARRAY_ALLOC),
++                            : event_var ? GFC_CAF_EVENT_ALLOC
++					: GFC_CAF_COARRAY_ALLOC),
+ 	     token, pstat, errmsg, errlen);
+ 
+   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
+ 			 TREE_TYPE (pointer), pointer,
+ 			 fold_convert ( TREE_TYPE (pointer), tmp));
+   gfc_add_expr_to_block (block, tmp);
++
++  /* It guarantees memory consistency within the same segment */
++  tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++    tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++		      gfc_build_string_const (1, ""),
++		      NULL_TREE, NULL_TREE,
++		      tree_cons (NULL_TREE, tmp, NULL_TREE),
++		      NULL_TREE);
++  ASM_VOLATILE_P (tmp) = 1;
++  gfc_add_expr_to_block (block, tmp);
+ }
+ 
+ 
+@@ -794,6 +820,11 @@
+ 			 == INTMOD_ISO_FORTRAN_ENV
+ 		      && expr->ts.u.derived->intmod_sym_id
+ 		         == ISOFORTRAN_LOCK_TYPE;
++      bool event_var = expr->ts.type == BT_DERIVED
++		       && expr->ts.u.derived->from_intmod
++			 == INTMOD_ISO_FORTRAN_ENV
++		       && expr->ts.u.derived->intmod_sym_id
++		         == ISOFORTRAN_EVENT_TYPE;
+       /* In the front end, we represent the lock variable as pointer. However,
+ 	 the FE only passes the pointer around and leaves the actual
+ 	 representation to the library. Hence, we have to convert back to the
+@@ -803,7 +834,7 @@
+ 				size, TYPE_SIZE_UNIT (ptr_type_node));
+ 
+       gfc_allocate_using_lib (&alloc_block, mem, size, token, status,
+-			      errmsg, errlen, lock_var);
++			      errmsg, errlen, lock_var, event_var);
+ 
+       if (status != NULL_TREE)
+ 	{
+@@ -1360,6 +1391,16 @@
+ 	     token, pstat, errmsg, errlen);
+       gfc_add_expr_to_block (&non_null, tmp);
+ 
++      /* It guarantees memory consistency within the same segment */
++      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++			  gfc_build_string_const (1, ""),
++			  NULL_TREE, NULL_TREE,
++			  tree_cons (NULL_TREE, tmp, NULL_TREE),
++			  NULL_TREE);
++      ASM_VOLATILE_P (tmp) = 1;
++      gfc_add_expr_to_block (&non_null, tmp);
++
+       if (status != NULL_TREE)
+ 	{
+ 	  tree stat = build_fold_indirect_ref_loc (input_location, status);
+@@ -1647,6 +1688,7 @@
+ 	  gfc_add_expr_to_block (&block, res);
+ 	}
+ 
++      gfc_current_locus = code->loc;
+       gfc_set_backend_locus (&code->loc);
+ 
+       switch (code->op)
+@@ -1808,6 +1850,11 @@
+ 	  res = gfc_trans_lock_unlock (code, code->op);
+ 	  break;
+ 
++	case EXEC_EVENT_POST:
++	case EXEC_EVENT_WAIT:
++	  res = gfc_trans_event_post_wait (code, code->op);
++	  break;
++
+ 	case EXEC_FORALL:
+ 	  res = gfc_trans_forall (code);
+ 	  break;
+--- a/gcc/fortran/trans-decl.c	2015-10-29 20:52:56.000000000 +0100
++++ b/gcc/fortran/trans-decl.c	2016-02-16 15:44:29.784760195 +0100
+@@ -163,6 +163,9 @@
+ tree gfor_fndecl_caf_atomic_op;
+ tree gfor_fndecl_caf_lock;
+ tree gfor_fndecl_caf_unlock;
++tree gfor_fndecl_caf_event_post;
++tree gfor_fndecl_caf_event_wait;
++tree gfor_fndecl_caf_event_query;
+ tree gfor_fndecl_co_broadcast;
+ tree gfor_fndecl_co_max;
+ tree gfor_fndecl_co_min;
+@@ -3505,6 +3508,21 @@
+ 	void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
+ 	pint_type, pchar_type_node, integer_type_node);
+ 
++      gfor_fndecl_caf_event_post = gfc_build_library_function_decl_with_spec (
++	get_identifier (PREFIX("caf_event_post")), "R..WW",
++	void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
++	pint_type, pchar_type_node, integer_type_node);
++
++      gfor_fndecl_caf_event_wait = gfc_build_library_function_decl_with_spec (
++	get_identifier (PREFIX("caf_event_wait")), "R..WW",
++	void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
++	pint_type, pchar_type_node, integer_type_node);
++
++      gfor_fndecl_caf_event_query = gfc_build_library_function_decl_with_spec (
++	get_identifier (PREFIX("caf_event_query")), "R..WW",
++	void_type_node, 5, pvoid_type_node, size_type_node, integer_type_node,
++	pint_type, pint_type);
++
+       gfor_fndecl_co_broadcast = gfc_build_library_function_decl_with_spec (
+ 	get_identifier (PREFIX("caf_co_broadcast")), "W.WW",
+ 	void_type_node, 5, pvoid_type_node, integer_type_node,
+@@ -4784,7 +4802,7 @@
+ generate_coarray_sym_init (gfc_symbol *sym)
+ {
+   tree tmp, size, decl, token;
+-  bool is_lock_type;
++  bool is_lock_type, is_event_type;
+   int reg_type;
+ 
+   if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
+@@ -4800,13 +4818,17 @@
+ 		 && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ 		 && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE;
+ 
++  is_event_type = sym->ts.type == BT_DERIVED
++		  && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++		  && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE;
++
+   /* FIXME: Workaround for PR middle-end/49106, cf. also PR middle-end/49108
+      to make sure the variable is not optimized away.  */
+   DECL_PRESERVE_P (DECL_CONTEXT (decl)) = 1;
+ 
+   /* For lock types, we pass the array size as only the library knows the
+      size of the variable.  */
+-  if (is_lock_type)
++  if (is_lock_type || is_event_type)
+     size = gfc_index_one_node;
+   else
+     size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (decl)));
+@@ -4828,6 +4850,8 @@
+ 			       GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE(decl)));
+   if (is_lock_type)
+     reg_type = sym->attr.artificial ? GFC_CAF_CRITICAL : GFC_CAF_LOCK_STATIC;
++  else if (is_event_type)
++    reg_type = GFC_CAF_EVENT_STATIC;
+   else
+     reg_type = GFC_CAF_COARRAY_STATIC;
+   tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 6, size,
+--- a/gcc/fortran/trans-expr.c	2015-11-04 21:00:19.000000000 +0100
++++ b/gcc/fortran/trans-expr.c	2016-02-16 15:44:29.785760212 +0100
+@@ -1,5 +1,5 @@
+ /* Expression translation
+-   Copyright (C) 2002-2015 Free Software Foundation, Inc.
++   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+    Contributed by Paul Brook <paul at nowt.org>
+    and Steven Bosscher <s.bosscher at student.tudelft.nl>
+ 
+@@ -1019,6 +1019,7 @@
+   tree fcn;
+   tree fcn_type;
+   tree from_data;
++  tree from_class_base = NULL;
+   tree from_len;
+   tree to_data;
+   tree to_len;
+@@ -1035,21 +1036,41 @@
+   from_len = to_len = NULL_TREE;
+ 
+   if (from != NULL_TREE)
+-    fcn = gfc_class_vtab_copy_get (from);
++    {
++      /* Check that from is a class.  When the class is part of a coarray,
++	 then from is a common pointer and is to be used as is.  */
++      tmp = POINTER_TYPE_P (TREE_TYPE (from)) && !DECL_P (from)
++	  ? TREE_OPERAND (from, 0) : from;
++      if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
++	  || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
++	{
++	  from_class_base = from;
++	  from_data = gfc_class_data_get (from_class_base);
++	}
++      else
++	{
++	  /* For arrays two component_refs can be present.  */
++	  if (TREE_CODE (tmp) == COMPONENT_REF)
++	    tmp = TREE_OPERAND (tmp, 0);
++	  if (TREE_CODE (tmp) == COMPONENT_REF)
++	    tmp = TREE_OPERAND (tmp, 0);
++	  from_class_base = tmp;
++	  from_data = from;
++	}
++      fcn = gfc_class_vtab_copy_get (from_class_base);
++    }
+   else
+-    fcn = gfc_class_vtab_copy_get (to);
++    {
++      fcn = gfc_class_vtab_copy_get (to);
++      from_data = gfc_class_vtab_def_init_get (to);
++    }
+ 
+   fcn_type = TREE_TYPE (TREE_TYPE (fcn));
+ 
+-  if (from != NULL_TREE)
+-      from_data = gfc_class_data_get (from);
+-  else
+-    from_data = gfc_class_vtab_def_init_get (to);
+-
+   if (unlimited)
+     {
+-      if (from != NULL_TREE && unlimited)
+-	from_len = gfc_class_len_get (from);
++      if (from_class_base != NULL_TREE)
++	from_len = gfc_class_len_get (from_class_base);
+       else
+ 	from_len = integer_zero_node;
+     }
+@@ -4398,6 +4419,62 @@
+ }
+ 
+ 
++/* This function tells whether the middle-end representation of the expression
++   E given as input may point to data otherwise accessible through a variable
++   (sub-)reference.
++   It is assumed that the only expressions that may alias are variables,
++   and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
++   may alias.
++   This function is used to decide whether freeing an expression's allocatable
++   components is safe or should be avoided.
++
++   If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
++   its elements are copied from a variable.  This ARRAY_MAY_ALIAS trick
++   is necessary because for array constructors, aliasing depends on how
++   the array is used:
++    - If E is an array constructor used as argument to an elemental procedure,
++      the array, which is generated through shallow copy by the scalarizer,
++      is used directly and can alias the expressions it was copied from.
++    - If E is an array constructor used as argument to a non-elemental
++      procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
++      the array as in the previous case, but then that array is used
++      to initialize a new descriptor through deep copy.  There is no alias
++      possible in that case.
++   Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
++   above.  */
++
++static bool
++expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
++{
++  gfc_constructor *c;
++
++  if (e->expr_type == EXPR_VARIABLE)
++    return true;
++  else if (e->expr_type == EXPR_FUNCTION)
++    {
++      gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
++
++      if ((proc_ifc->result->ts.type == BT_CLASS
++	   && proc_ifc->result->ts.u.derived->attr.is_class
++	   && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
++	  || proc_ifc->result->attr.pointer)
++	return true;
++      else
++	return false;
++    }
++  else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
++    return false;
++
++  for (c = gfc_constructor_first (e->value.constructor);
++       c; c = gfc_constructor_next (c))
++    if (c->expr
++	&& expr_may_alias_variables (c->expr, array_may_alias))
++      return true;
++
++  return false;
++}
++
++
+ /* Generate code for a procedure call.  Note can return se->post != NULL.
+    If se->direct_byref is set then se->expr contains the return parameter.
+    Return nonzero, if the call has alternate specifiers.
+@@ -4448,9 +4525,15 @@
+ 
+   comp = gfc_get_proc_ptr_comp (expr);
+ 
++  bool elemental_proc = (comp
++			 && comp->ts.interface
++			 && comp->ts.interface->attr.elemental)
++			|| (comp && comp->attr.elemental)
++			|| sym->attr.elemental;
++
+   if (se->ss != NULL)
+     {
+-      if (!sym->attr.elemental && !(comp && comp->attr.elemental))
++      if (!elemental_proc)
+ 	{
+ 	  gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
+ 	  if (se->ss->info->useflags)
+@@ -4501,6 +4584,23 @@
+       fsym = formal ? formal->sym : NULL;
+       parm_kind = MISSING;
+ 
++      /* If the procedure requires an explicit interface, the actual
++	 argument is passed according to the corresponding formal
++	 argument.  If the corresponding formal argument is a POINTER,
++	 ALLOCATABLE or assumed shape, we do not use g77's calling
++	 convention, and pass the address of the array descriptor
++	 instead.  Otherwise we use g77's calling convention, in other words
++	 pass the array data pointer without descriptor.  */
++      bool nodesc_arg = fsym != NULL
++			&& !(fsym->attr.pointer || fsym->attr.allocatable)
++			&& fsym->as
++			&& fsym->as->type != AS_ASSUMED_SHAPE
++			&& fsym->as->type != AS_ASSUMED_RANK;
++      if (comp)
++	nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
++      else
++	nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
++
+       /* Class array expressions are sometimes coming completely unadorned
+ 	 with either arrayspec or _data component.  Correct that here.
+ 	 OOP-TODO: Move this to the frontend.  */
+@@ -5020,22 +5120,6 @@
+ 	    }
+ 	  else
+ 	    {
+-              /* If the procedure requires an explicit interface, the actual
+-                 argument is passed according to the corresponding formal
+-                 argument.  If the corresponding formal argument is a POINTER,
+-                 ALLOCATABLE or assumed shape, we do not use g77's calling
+-                 convention, and pass the address of the array descriptor
+-                 instead. Otherwise we use g77's calling convention.  */
+-	      bool f;
+-	      f = (fsym != NULL)
+-		  && !(fsym->attr.pointer || fsym->attr.allocatable)
+-		  && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE
+-		  && fsym->as->type != AS_ASSUMED_RANK;
+-	      if (comp)
+-		f = f || !comp->attr.always_explicit;
+-	      else
+-		f = f || !sym->attr.always_explicit;
+-
+ 	      /* If the argument is a function call that may not create
+ 		 a temporary for the result, we have to check that we
+ 		 can do it, i.e. that there is no alias between this
+@@ -5080,7 +5164,7 @@
+ 		   array of derived types.  In this case, the argument
+ 		   is converted to a temporary, which is passed and then
+ 		   written back after the procedure call.  */
+-		gfc_conv_subref_array_arg (&parmse, e, f,
++		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
+ 				fsym ? fsym->attr.intent : INTENT_INOUT,
+ 				fsym && fsym->attr.pointer);
+ 	      else if (gfc_is_class_array_ref (e, NULL)
+@@ -5092,7 +5176,7 @@
+ 		   OOP-TODO: Insert code so that if the dynamic type is
+ 		   the same as the declared type, copy-in/copy-out does
+ 		   not occur.  */
+-		gfc_conv_subref_array_arg (&parmse, e, f,
++		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
+ 				fsym ? fsym->attr.intent : INTENT_INOUT,
+ 				fsym && fsym->attr.pointer);
+ 
+@@ -5103,12 +5187,13 @@
+ 		   intent in.  */
+ 		{
+ 		  e->must_finalize = 1;
+-		  gfc_conv_subref_array_arg (&parmse, e, f,
++		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
+ 					     INTENT_IN,
+ 					     fsym && fsym->attr.pointer);
+ 		}
+ 	      else
+-	        gfc_conv_array_parameter (&parmse, e, f, fsym, sym->name, NULL);
++		gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
++					  sym->name, NULL);
+ 
+ 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
+ 		 allocated on entry, it must be deallocated.  */
+@@ -5150,7 +5235,7 @@
+ 	     but do not always set fsym.  */
+ 	  if (e->expr_type == EXPR_VARIABLE
+ 	      && e->symtree->n.sym->attr.optional
+-	      && ((e->rank != 0 && sym->attr.elemental)
++	      && ((e->rank != 0 && elemental_proc)
+ 		  || e->representation.length || e->ts.type == BT_CHARACTER
+ 		  || (e->rank != 0
+ 		      && (fsym == NULL
+@@ -5185,13 +5270,16 @@
+       gfc_add_block_to_block (&post, &parmse.post);
+ 
+       /* Allocated allocatable components of derived types must be
+-	 deallocated for non-variable scalars.  Non-variable arrays are
+-	 dealt with in trans-array.c(gfc_conv_array_parameter).  */
++	 deallocated for non-variable scalars, array arguments to elemental
++	 procedures, and array arguments with descriptor to non-elemental
++	 procedures.  As bounds information for descriptorless arrays is no
++	 longer available here, they are dealt with in trans-array.c
++	 (gfc_conv_array_parameter).  */
+       if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
+ 	    && e->ts.u.derived->attr.alloc_comp
+-	    && !(e->symtree && e->symtree->n.sym->attr.pointer)
+-	    && (e->expr_type != EXPR_VARIABLE && !e->rank))
+-        {
++	    && (e->rank == 0 || elemental_proc || !nodesc_arg)
++	    && !expr_may_alias_variables (e, elemental_proc))
++	{
+ 	  int parm_rank;
+ 	  tmp = build_fold_indirect_ref_loc (input_location,
+ 					 parmse.expr);
+@@ -5343,7 +5431,8 @@
+ 	  else
+ 	    {
+ 	      tmp = parmse.string_length;
+-	      if (TREE_CODE (tmp) != VAR_DECL)
++	      if (TREE_CODE (tmp) != VAR_DECL
++		  && TREE_CODE (tmp) != COMPONENT_REF)
+ 		tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
+ 	      parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
+ 	    }
+@@ -5527,8 +5616,9 @@
+       len = cl.backend_decl;
+     }
+ 
+-  byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
+-	  || (!comp && gfc_return_by_reference (sym));
++  byref = (comp && (comp->attr.dimension
++	   || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
++	   || (!comp && gfc_return_by_reference (sym));
+   if (byref)
+     {
+       if (se->direct_byref)
+@@ -6354,6 +6444,11 @@
+ {
+   gfc_se se;
+ 
++  if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
++      && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++      && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
++    return build_constructor (type, NULL);
++
+   if (!(expr || pointer || procptr))
+     return NULL_TREE;
+ 
+@@ -6518,7 +6613,7 @@
+ 
+   gfc_conv_expr (&rse, expr);
+ 
+-  tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
++  tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, true, true);
+   gfc_add_expr_to_block (&body, tmp);
+ 
+   gcc_assert (rse.ss == gfc_ss_terminator);
+@@ -7403,20 +7498,6 @@
+ 
+   /* Take the address of that value.  */
+   se->expr = gfc_build_addr_expr (NULL_TREE, var);
+-  if (expr->ts.type == BT_DERIVED && expr->rank
+-      && !gfc_is_finalizable (expr->ts.u.derived, NULL)
+-      && expr->ts.u.derived->attr.alloc_comp
+-      && expr->expr_type != EXPR_VARIABLE)
+-    {
+-      tree tmp;
+-
+-      tmp = build_fold_indirect_ref_loc (input_location, se->expr);
+-      tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
+-
+-      /* The components shall be deallocated before
+-         their containing entity.  */
+-      gfc_prepend_expr_to_block (&se->post, tmp);
+-    }
+ }
+ 
+ 
+@@ -8901,6 +8982,7 @@
+   bool scalar_to_array;
+   tree string_length;
+   int n;
++  bool maybe_workshare = false;
+ 
+   /* Assignment of the form lhs = rhs.  */
+   gfc_start_block (&block);
+@@ -8975,8 +9057,13 @@
+ 	}
+ 
+       /* Allow the scalarizer to workshare array assignments.  */
+-      if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
+-	ompws_flags |= OMPWS_SCALARIZER_WS;
++      if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
++	  == OMPWS_WORKSHARE_FLAG
++	  && loop.temp_ss == NULL)
++	{
++	  maybe_workshare = true;
++	  ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
++	}
+ 
+       /* Start the scalarized loop body.  */
+       gfc_start_scalarized_body (&loop, &body);
+@@ -8998,8 +9085,10 @@
+     }
+ 
+   /* Stabilize a string length for temporaries.  */
+-  if (expr2->ts.type == BT_CHARACTER)
++  if (expr2->ts.type == BT_CHARACTER && !expr2->ts.deferred)
+     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
++  else if (expr2->ts.type == BT_CHARACTER)
++    string_length = rse.string_length;
+   else
+     string_length = NULL_TREE;
+ 
+@@ -9033,8 +9122,14 @@
+      the function call must happen before the (re)allocation of the lhs -
+      otherwise the character length of the result is not known.
+      NOTE: This relies on having the exact dependence of the length type
+-     parameter available to the caller; gfortran saves it in the .mod files.  */
+-  if (flag_realloc_lhs && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred)
++     parameter available to the caller; gfortran saves it in the .mod files.
++     NOTE ALSO: The concatenation operation generates a temporary pointer,
++     whose allocation must go to the innermost loop.  */
++  if (flag_realloc_lhs
++      && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
++      && !(lss != gfc_ss_terminator
++	   && expr2->expr_type == EXPR_OP
++	   && expr2->value.op.op == INTRINSIC_CONCAT))
+     gfc_add_block_to_block (&block, &rse.pre);
+ 
+   /* Nullify the allocatable components corresponding to those of the lhs
+@@ -9117,6 +9212,9 @@
+ 	    gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
+ 	}
+ 
++      if (maybe_workshare)
++	ompws_flags &= ~OMPWS_SCALARIZER_BODY;
++
+       /* Generate the copying loops.  */
+       gfc_trans_scalarizing_loops (&loop, &body);
+ 
+--- a/gcc/fortran/trans.h	2015-03-24 11:28:48.000000000 +0100
++++ b/gcc/fortran/trans.h	2016-02-16 15:44:29.788760264 +0100
+@@ -109,7 +109,9 @@
+   GFC_CAF_COARRAY_ALLOC,
+   GFC_CAF_LOCK_STATIC,
+   GFC_CAF_LOCK_ALLOC,
+-  GFC_CAF_CRITICAL
++  GFC_CAF_CRITICAL,
++  GFC_CAF_EVENT_STATIC,
++  GFC_CAF_EVENT_ALLOC
+ }
+ gfc_coarray_type;
+ 
+@@ -756,6 +758,9 @@
+ extern GTY(()) tree gfor_fndecl_caf_atomic_op;
+ extern GTY(()) tree gfor_fndecl_caf_lock;
+ extern GTY(()) tree gfor_fndecl_caf_unlock;
++extern GTY(()) tree gfor_fndecl_caf_event_post;
++extern GTY(()) tree gfor_fndecl_caf_event_wait;
++extern GTY(()) tree gfor_fndecl_caf_event_query;
+ extern GTY(()) tree gfor_fndecl_co_broadcast;
+ extern GTY(()) tree gfor_fndecl_co_max;
+ extern GTY(()) tree gfor_fndecl_co_min;
+@@ -1027,7 +1032,9 @@
+ 					   construct is not workshared.  */
+ #define OMPWS_SCALARIZER_WS	4	/* Set if scalarizer should attempt
+ 					   to create parallel loops.  */
+-#define OMPWS_NOWAIT		8	/* Use NOWAIT on OMP_FOR.  */
++#define OMPWS_SCALARIZER_BODY	8	/* Set if handling body of potential
++					   parallel loop.  */
++#define OMPWS_NOWAIT		16	/* Use NOWAIT on OMP_FOR.  */
+ extern int ompws_flags;
+ 
+ #endif /* GFC_TRANS_H */
+--- a/gcc/fortran/trans-intrinsic.c	2015-10-26 18:25:03.000000000 +0100
++++ b/gcc/fortran/trans-intrinsic.c	2016-02-16 15:44:29.786760229 +0100
+@@ -1221,12 +1221,22 @@
+   /* No overlap possible as we have generated a temporary.  */
+   if (lhs == NULL_TREE)
+     may_require_tmp = boolean_false_node;
++  
++  /* It guarantees memory consistency within the same segment */
++  tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++    tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++		      gfc_build_string_const (1, ""),
++		      NULL_TREE, NULL_TREE,
++		      tree_cons (NULL_TREE, tmp, NULL_TREE),
++		      NULL_TREE);
++  ASM_VOLATILE_P (tmp) = 1;
++  gfc_add_expr_to_block (&se->pre, tmp);
+ 
+   tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_get, 9,
+ 			     token, offset, image_index, argse.expr, vec,
+ 			     dst_var, kind, lhs_kind, may_require_tmp);
+   gfc_add_expr_to_block (&se->pre, tmp);
+-
++  
+   if (se->ss)
+     gfc_advance_se_ss_chain (se);
+ 
+@@ -1386,6 +1396,16 @@
+     {
+       tree rhs_token, rhs_offset, rhs_image_index;
+ 
++      /* It guarantees memory consistency within the same segment */
++      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++			  gfc_build_string_const (1, ""),
++			  NULL_TREE, NULL_TREE,
++			  tree_cons (NULL_TREE, tmp, NULL_TREE),
++			  NULL_TREE);
++      ASM_VOLATILE_P (tmp) = 1;
++      gfc_add_expr_to_block (&block, tmp);
++
+       caf_decl = gfc_get_tree_for_caf_expr (rhs_expr);
+       if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
+ 	caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
+@@ -1401,6 +1421,17 @@
+   gfc_add_expr_to_block (&block, tmp);
+   gfc_add_block_to_block (&block, &lhs_se.post);
+   gfc_add_block_to_block (&block, &rhs_se.post);
++
++  /* It guarantees memory consistency within the same segment */
++  tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++    tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++		      gfc_build_string_const (1, ""),
++		      NULL_TREE, NULL_TREE,
++		      tree_cons (NULL_TREE, tmp, NULL_TREE),
++		      NULL_TREE);
++  ASM_VOLATILE_P (tmp) = 1;
++  gfc_add_expr_to_block (&block, tmp);
++
+   return gfc_finish_block (&block);
+ }
+ 
+@@ -9243,6 +9274,154 @@
+   return gfc_finish_block (&block);
+ }
+ 
++static tree
++conv_intrinsic_event_query (gfc_code *code)
++{
++  gfc_se se, argse;
++  tree stat = NULL_TREE, stat2 = NULL_TREE;
++  tree count = NULL_TREE, count2 = NULL_TREE;
++
++  gfc_expr *event_expr = code->ext.actual->expr;
++
++  if (code->ext.actual->next->next->expr)
++    {
++      gcc_assert (code->ext.actual->next->next->expr->expr_type
++		  == EXPR_VARIABLE);
++      gfc_init_se (&argse, NULL);
++      gfc_conv_expr_val (&argse, code->ext.actual->next->next->expr);
++      stat = argse.expr;
++    }
++  else if (flag_coarray == GFC_FCOARRAY_LIB)
++    stat = null_pointer_node;
++
++  if (code->ext.actual->next->expr)
++    {
++      gcc_assert (code->ext.actual->next->expr->expr_type == EXPR_VARIABLE);
++      gfc_init_se (&argse, NULL);
++      gfc_conv_expr_val (&argse, code->ext.actual->next->expr);
++      count = argse.expr;
++    }
++
++  gfc_start_block (&se.pre);
++  if (flag_coarray == GFC_FCOARRAY_LIB)
++    {
++      tree tmp, token, image_index;
++      tree index = size_zero_node;
++
++      if (event_expr->expr_type == EXPR_FUNCTION
++	  && event_expr->value.function.isym
++	  && event_expr->value.function.isym->id == GFC_ISYM_CAF_GET)
++	event_expr = event_expr->value.function.actual->expr;
++
++      tree caf_decl = gfc_get_tree_for_caf_expr (event_expr);
++
++      if (event_expr->symtree->n.sym->ts.type != BT_DERIVED
++	  || event_expr->symtree->n.sym->ts.u.derived->from_intmod
++	     != INTMOD_ISO_FORTRAN_ENV
++	  || event_expr->symtree->n.sym->ts.u.derived->intmod_sym_id
++	     != ISOFORTRAN_EVENT_TYPE)
++	{
++	  gfc_error ("Sorry, the event component of derived type at %L is not "
++		     "yet supported", &event_expr->where);
++	  return NULL_TREE;
++	}
++
++      if (gfc_is_coindexed (event_expr))
++	{
++	  gfc_error ("The event variable at %L shall not be coindexed ",
++		     &event_expr->where);
++          return NULL_TREE;
++	}
++
++      image_index = integer_zero_node;
++
++      gfc_get_caf_token_offset (&token, NULL, caf_decl, NULL_TREE, event_expr);
++
++      /* For arrays, obtain the array index.  */
++      if (gfc_expr_attr (event_expr).dimension)
++	{
++	  tree desc, tmp, extent, lbound, ubound;
++          gfc_array_ref *ar, ar2;
++          int i;
++
++	  /* TODO: Extend this, once DT components are supported.  */
++	  ar = &event_expr->ref->u.ar;
++	  ar2 = *ar;
++	  memset (ar, '\0', sizeof (*ar));
++	  ar->as = ar2.as;
++	  ar->type = AR_FULL;
++
++	  gfc_init_se (&argse, NULL);
++	  argse.descriptor_only = 1;
++	  gfc_conv_expr_descriptor (&argse, event_expr);
++	  gfc_add_block_to_block (&se.pre, &argse.pre);
++	  desc = argse.expr;
++	  *ar = ar2;
++
++	  extent = integer_one_node;
++	  for (i = 0; i < ar->dimen; i++)
++	    {
++	      gfc_init_se (&argse, NULL);
++	      gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
++	      gfc_add_block_to_block (&argse.pre, &argse.pre);
++	      lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
++	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
++				     integer_type_node, argse.expr,
++				     fold_convert(integer_type_node, lbound));
++	      tmp = fold_build2_loc (input_location, MULT_EXPR,
++				     integer_type_node, extent, tmp);
++	      index = fold_build2_loc (input_location, PLUS_EXPR,
++				       integer_type_node, index, tmp);
++	      if (i < ar->dimen - 1)
++		{
++		  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
++		  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
++		  tmp = fold_convert (integer_type_node, tmp);
++		  extent = fold_build2_loc (input_location, MULT_EXPR,
++					    integer_type_node, extent, tmp);
++		}
++	    }
++	}
++
++      if (count != null_pointer_node && TREE_TYPE (count) != integer_type_node)
++	{
++	  count2 = count;
++	  count = gfc_create_var (integer_type_node, "count");
++	}
++
++      if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
++	{
++	  stat2 = stat;
++	  stat = gfc_create_var (integer_type_node, "stat");
++	}
++
++      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_query, 5,
++                                   token, index, image_index, count
++				   ? gfc_build_addr_expr (NULL, count) : count,
++				   stat != null_pointer_node
++				   ? gfc_build_addr_expr (NULL, stat) : stat);
++      gfc_add_expr_to_block (&se.pre, tmp);
++
++      if (count2 != NULL_TREE)
++	gfc_add_modify (&se.pre, count2,
++			fold_convert (TREE_TYPE (count2), count));
++
++      if (stat2 != NULL_TREE)
++	gfc_add_modify (&se.pre, stat2,
++			fold_convert (TREE_TYPE (stat2), stat));
++
++      return gfc_finish_block (&se.pre);
++    }
++
++  gfc_init_se (&argse, NULL);
++  gfc_conv_expr_val (&argse, code->ext.actual->expr);
++  gfc_add_modify (&se.pre, count, fold_convert (TREE_TYPE (count), argse.expr));
++
++  if (stat != NULL_TREE)
++    gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
++
++  return gfc_finish_block (&se.pre);
++}
+ 
+ static tree
+ conv_intrinsic_move_alloc (gfc_code *code)
+@@ -9539,6 +9718,10 @@
+       res = conv_intrinsic_atomic_ref (code);
+       break;
+ 
++    case GFC_ISYM_EVENT_QUERY:
++      res = conv_intrinsic_event_query (code);
++      break;
++
+     case GFC_ISYM_C_F_POINTER:
+     case GFC_ISYM_C_F_PROCPOINTER:
+       res = conv_isocbinding_subroutine (code);
+--- a/gcc/fortran/trans-openmp.c	2015-10-18 17:01:03.000000000 +0200
++++ b/gcc/fortran/trans-openmp.c	2016-02-16 15:42:04.615303641 +0100
+@@ -4255,7 +4255,7 @@
+ 
+       /* By default, every gfc_code is a single unit of work.  */
+       ompws_flags |= OMPWS_CURR_SINGLEUNIT;
+-      ompws_flags &= ~OMPWS_SCALARIZER_WS;
++      ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY);
+ 
+       switch (code->op)
+ 	{
+--- a/gcc/fortran/trans-stmt.c	2015-10-22 20:05:21.000000000 +0200
++++ b/gcc/fortran/trans-stmt.c	2016-02-16 15:44:29.787760247 +0100
+@@ -1,5 +1,5 @@
+ /* Statement translation -- generate GCC trees from gfc_code.
+-   Copyright (C) 2002-2015 Free Software Foundation, Inc.
++   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+    Contributed by Paul Brook <paul at nowt.org>
+    and Steven Bosscher <s.bosscher at student.tudelft.nl>
+ 
+@@ -788,6 +788,7 @@
+       if (code->expr3)
+ 	{
+ 	  gfc_init_se (&argse, NULL);
++	  argse.want_pointer = 1;
+ 	  gfc_conv_expr (&argse, code->expr3);
+ 	  gfc_add_block_to_block (&se.pre, &argse.pre);
+ 	  errmsg = argse.expr;
+@@ -829,6 +830,17 @@
+ 				   errmsg, errmsg_len);
+       gfc_add_expr_to_block (&se.pre, tmp);
+ 
++      /* It guarantees memory consistency within the same segment */
++      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++			  gfc_build_string_const (1, ""),
++			  NULL_TREE, NULL_TREE,
++			  tree_cons (NULL_TREE, tmp, NULL_TREE),
++			  NULL_TREE);
++      ASM_VOLATILE_P (tmp) = 1;
++
++      gfc_add_expr_to_block (&se.pre, tmp);
++
+       if (stat2 != NULL_TREE)
+ 	gfc_add_modify (&se.pre, stat2,
+ 			fold_convert (TREE_TYPE (stat2), stat));
+@@ -852,6 +864,165 @@
+   return gfc_finish_block (&se.pre);
+ }
+ 
++tree
++gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
++{
++  gfc_se se, argse;
++  tree stat = NULL_TREE, stat2 = NULL_TREE;
++  tree until_count = NULL_TREE;
++
++  if (code->expr2)
++    {
++      gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
++      gfc_init_se (&argse, NULL);
++      gfc_conv_expr_val (&argse, code->expr2);
++      stat = argse.expr;
++    }
++  else if (flag_coarray == GFC_FCOARRAY_LIB)
++    stat = null_pointer_node;
++
++  if (code->expr4)
++    {
++      gfc_init_se (&argse, NULL);
++      gfc_conv_expr_val (&argse, code->expr4);
++      until_count = fold_convert (integer_type_node, argse.expr);
++    }
++  else
++    until_count = integer_one_node;
++
++  if (flag_coarray != GFC_FCOARRAY_LIB)
++    {
++      gfc_start_block (&se.pre);
++      gfc_init_se (&argse, NULL);
++      gfc_conv_expr_val (&argse, code->expr1);
++
++      if (op == EXEC_EVENT_POST)
++	gfc_add_modify (&se.pre, argse.expr,
++			fold_build2_loc (input_location, PLUS_EXPR,
++				TREE_TYPE (argse.expr), argse.expr,
++				build_int_cst (TREE_TYPE (argse.expr), 1)));
++      else
++	gfc_add_modify (&se.pre, argse.expr,
++			fold_build2_loc (input_location, MINUS_EXPR,
++				TREE_TYPE (argse.expr), argse.expr,
++				fold_convert (TREE_TYPE (argse.expr),
++					      until_count)));
++      if (stat != NULL_TREE)
++	gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
++
++      return gfc_finish_block (&se.pre);
++    }
++
++  gfc_start_block (&se.pre);
++  tree tmp, token, image_index, errmsg, errmsg_len;
++  tree index = size_zero_node;
++  tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
++
++  if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
++      || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
++	 != INTMOD_ISO_FORTRAN_ENV
++      || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
++	 != ISOFORTRAN_EVENT_TYPE)
++    {
++      gfc_error ("Sorry, the event component of derived type at %L is not "
++		 "yet supported", &code->expr1->where);
++      return NULL_TREE;
++    }
++
++  gfc_get_caf_token_offset (&token, NULL, caf_decl, NULL_TREE, code->expr1);
++
++  if (gfc_is_coindexed (code->expr1))
++    image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
++  else
++    image_index = integer_zero_node;
++
++  /* For arrays, obtain the array index.  */
++  if (gfc_expr_attr (code->expr1).dimension)
++    {
++      tree desc, tmp, extent, lbound, ubound;
++      gfc_array_ref *ar, ar2;
++      int i;
++
++      /* TODO: Extend this, once DT components are supported.  */
++      ar = &code->expr1->ref->u.ar;
++      ar2 = *ar;
++      memset (ar, '\0', sizeof (*ar));
++      ar->as = ar2.as;
++      ar->type = AR_FULL;
++
++      gfc_init_se (&argse, NULL);
++      argse.descriptor_only = 1;
++      gfc_conv_expr_descriptor (&argse, code->expr1);
++      gfc_add_block_to_block (&se.pre, &argse.pre);
++      desc = argse.expr;
++      *ar = ar2;
++
++      extent = integer_one_node;
++      for (i = 0; i < ar->dimen; i++)
++	{
++	  gfc_init_se (&argse, NULL);
++	  gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
++	  gfc_add_block_to_block (&argse.pre, &argse.pre);
++	  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
++	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
++				 integer_type_node, argse.expr,
++				 fold_convert(integer_type_node, lbound));
++	  tmp = fold_build2_loc (input_location, MULT_EXPR,
++				 integer_type_node, extent, tmp);
++	  index = fold_build2_loc (input_location, PLUS_EXPR,
++				   integer_type_node, index, tmp);
++	  if (i < ar->dimen - 1)
++	    {
++	      ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
++	      tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
++	      tmp = fold_convert (integer_type_node, tmp);
++	      extent = fold_build2_loc (input_location, MULT_EXPR,
++					integer_type_node, extent, tmp);
++	    }
++	}
++    }
++
++  /* errmsg.  */
++  if (code->expr3)
++    {
++      gfc_init_se (&argse, NULL);
++      argse.want_pointer = 1;
++      gfc_conv_expr (&argse, code->expr3);
++      gfc_add_block_to_block (&se.pre, &argse.pre);
++      errmsg = argse.expr;
++      errmsg_len = fold_convert (integer_type_node, argse.string_length);
++    }
++  else
++    {
++      errmsg = null_pointer_node;
++      errmsg_len = integer_zero_node;
++    }
++
++  if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
++    {
++      stat2 = stat;
++      stat = gfc_create_var (integer_type_node, "stat");
++    }
++
++  if (op == EXEC_EVENT_POST)
++    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
++			       token, index, image_index,
++			       stat != null_pointer_node
++			       ? gfc_build_addr_expr (NULL, stat) : stat,
++			       errmsg, errmsg_len);
++  else
++    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
++			       token, index, until_count,
++			       stat != null_pointer_node
++			       ? gfc_build_addr_expr (NULL, stat) : stat,
++			       errmsg, errmsg_len);
++  gfc_add_expr_to_block (&se.pre, tmp);
++
++  if (stat2 != NULL_TREE)
++    gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
++
++  return gfc_finish_block (&se.pre);
++}
+ 
+ tree
+ gfc_trans_sync (gfc_code *code, gfc_exec_op type)
+@@ -891,6 +1062,7 @@
+     {
+       gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
+       gfc_init_se (&argse, NULL);
++      argse.want_pointer = 1;
+       gfc_conv_expr (&argse, code->expr3);
+       gfc_conv_string_parameter (&argse);
+       errmsg = gfc_build_addr_expr (NULL, argse.expr);
+@@ -931,6 +1103,20 @@
+ 			       fold_convert (integer_type_node, images));
+     }
+ 
++  /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
++     image control statements SYNC IMAGES and SYNC ALL.  */
++  if (flag_coarray == GFC_FCOARRAY_LIB)
++    {
++      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++			  gfc_build_string_const (1, ""),
++			  NULL_TREE, NULL_TREE,
++			  tree_cons (NULL_TREE, tmp, NULL_TREE),
++			  NULL_TREE);
++      ASM_VOLATILE_P (tmp) = 1;
++      gfc_add_expr_to_block (&se.pre, tmp);
++    }
++
+   if (flag_coarray != GFC_FCOARRAY_LIB)
+     {
+       /* Set STAT to zero.  */
+@@ -1250,6 +1436,17 @@
+ 				 null_pointer_node, null_pointer_node,
+ 				 null_pointer_node, integer_zero_node);
+       gfc_add_expr_to_block (&block, tmp);
++
++      /* It guarantees memory consistency within the same segment */
++      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++			  gfc_build_string_const (1, ""),
++			  NULL_TREE, NULL_TREE,
++			  tree_cons (NULL_TREE, tmp, NULL_TREE),
++			  NULL_TREE);
++      ASM_VOLATILE_P (tmp) = 1;
++
++      gfc_add_expr_to_block (&block, tmp);
+     }
+ 
+   tmp = gfc_trans_code (code->block->next);
+@@ -1262,8 +1459,18 @@
+ 				 null_pointer_node, null_pointer_node,
+ 				 integer_zero_node);
+       gfc_add_expr_to_block (&block, tmp);
+-    }
+ 
++      /* It guarantees memory consistency within the same segment */
++      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
++	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
++			  gfc_build_string_const (1, ""),
++			  NULL_TREE, NULL_TREE,
++			  tree_cons (NULL_TREE, tmp, NULL_TREE),
++			  NULL_TREE);
++      ASM_VOLATILE_P (tmp) = 1;
++
++      gfc_add_expr_to_block (&block, tmp);
++    }
+ 
+   return gfc_finish_block (&block);
+ }
+@@ -4839,10 +5046,15 @@
+   gfc_loopinfo loop;
+   gfc_ss *edss = 0;
+   gfc_ss *esss = 0;
++  bool maybe_workshare = false;
+ 
+   /* Allow the scalarizer to workshare simple where loops.  */
+-  if (ompws_flags & OMPWS_WORKSHARE_FLAG)
+-    ompws_flags |= OMPWS_SCALARIZER_WS;
++  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
++      == OMPWS_WORKSHARE_FLAG)
++    {
++      maybe_workshare = true;
++      ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
++    }
+ 
+   cond = cblock->expr1;
+   tdst = cblock->next->expr1;
+@@ -4942,6 +5154,8 @@
+   gfc_add_expr_to_block (&body, tmp);
+   gfc_add_block_to_block (&body, &cse.post);
+ 
++  if (maybe_workshare)
++    ompws_flags &= ~OMPWS_SCALARIZER_BODY;
+   gfc_trans_scalarizing_loops (&loop, &body);
+   gfc_add_block_to_block (&block, &loop.pre);
+   gfc_add_block_to_block (&block, &loop.post);
+@@ -5062,7 +5276,7 @@
+ gfc_trans_allocate (gfc_code * code)
+ {
+   gfc_alloc *al;
+-  gfc_expr *expr;
++  gfc_expr *expr, *e3rhs = NULL;
+   gfc_se se, se_sz;
+   tree tmp;
+   tree parm;
+@@ -5073,6 +5287,7 @@
+   tree label_finish;
+   tree memsz;
+   tree al_vptr, al_len;
++  tree def_str_len = NULL_TREE;
+   /* If an expr3 is present, then store the tree for accessing its
+      _vptr, and _len components in the variables, respectively.  The
+      element size, i.e. _vptr%size, is stored in expr3_esize.  Any of
+@@ -5083,6 +5298,7 @@
+   stmtblock_t post;
+   tree nelems;
+   bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
++  gfc_symtree *newsym = NULL;
+ 
+   if (!code->ext.alloc.list)
+     return NULL_TREE;
+@@ -5132,7 +5348,7 @@
+      _vptr, _len and element_size for expr3.  */
+   if (code->expr3)
+     {
+-      bool vtab_needed = false;
++      bool vtab_needed = false, is_coarray = gfc_is_coarray (code->expr3);
+       /* expr3_tmp gets the tree when code->expr3.mold is set, i.e.,
+ 	 the expression is only needed to get the _vptr, _len a.s.o.  */
+       tree expr3_tmp = NULL_TREE;
+@@ -5192,16 +5408,29 @@
+ 					 false, false);
+ 	      gfc_add_block_to_block (&block, &se.pre);
+ 	      gfc_add_block_to_block (&post, &se.post);
+-	      /* Prevent aliasing, i.e., se.expr may be already a
+-		 variable declaration.  */
++
+ 	      if (!VAR_P (se.expr))
+ 		{
+-		  tmp = build_fold_indirect_ref_loc (input_location,
++		  tree var;
++
++		  tmp = is_coarray ? se.expr
++				  : build_fold_indirect_ref_loc (input_location,
+ 						     se.expr);
+-		  tmp = gfc_evaluate_now (tmp, &block);
++
++		  /* We need a regular (non-UID) symbol here, therefore give a
++		     prefix.  */
++		  var = gfc_create_var (TREE_TYPE (tmp), "source");
++		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
++		    {
++		      gfc_allocate_lang_decl (var);
++		      GFC_DECL_SAVED_DESCRIPTOR (var) = GFC_DECL_SAVED_DESCRIPTOR (tmp);
++		    }
++		  gfc_add_modify_loc (input_location, &block, var, tmp);
++		  tmp = var;
+ 		}
+ 	      else
+ 		tmp = se.expr;
++
+ 	      if (!code->expr3->mold)
+ 		expr3 = tmp;
+ 	      else
+@@ -5237,6 +5466,16 @@
+ 	  else if (expr3_tmp != NULL_TREE
+ 		   && (VAR_P (expr3_tmp) ||!code->expr3->ref))
+ 	    tmp = gfc_class_vptr_get (expr3_tmp);
++	  else if (is_coarray && expr3 != NULL_TREE)
++	    {
++	      /* Get the ref to coarray's data.  May be wrapped in a
++		 NOP_EXPR.  */
++	      tmp = POINTER_TYPE_P (TREE_TYPE (expr3)) ? TREE_OPERAND (expr3, 0)
++						       : tmp;
++	      /* Get to the base variable, i.e., strip _data.data.  */
++	      tmp = TREE_OPERAND (TREE_OPERAND (tmp, 0), 0);
++	      tmp = gfc_class_vptr_get (tmp);
++	    }
+ 	  else
+ 	    {
+ 	      rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
+@@ -5310,6 +5549,71 @@
+ 	  else
+ 	    expr3_esize = TYPE_SIZE_UNIT (
+ 		  gfc_typenode_for_spec (&code->expr3->ts));
++
++	  /* The routine gfc_trans_assignment () already implements all
++	     techniques needed.  Unfortunately we may have a temporary
++	     variable for the source= expression here.  When that is the
++	     case convert this variable into a temporary gfc_expr of type
++	     EXPR_VARIABLE and used it as rhs for the assignment.  The
++	     advantage is, that we get scalarizer support for free,
++	     don't have to take care about scalar to array treatment and
++	     will benefit of every enhancements gfc_trans_assignment ()
++	     gets.
++	     Exclude variables since the following block does not handle
++	     array sections.  In any case, there is no harm in sending
++	     variables to gfc_trans_assignment because there is no
++	     evaluation of variables.  */
++	  if (code->expr3->expr_type != EXPR_VARIABLE
++	      && code->expr3->mold != 1 && expr3 != NULL_TREE
++	      && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
++	    {
++	      /* Build a temporary symtree and symbol.  Do not add it to
++		 the current namespace to prevent accidently modifying
++		 a colliding symbol's as.  */
++	      newsym = XCNEW (gfc_symtree);
++	      /* The name of the symtree should be unique, because
++		 gfc_create_var () took care about generating the
++		 identifier.  */
++	      newsym->name = gfc_get_string (IDENTIFIER_POINTER (
++					       DECL_NAME (expr3)));
++	      newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
++	      /* The backend_decl is known.  It is expr3, which is inserted
++		 here.  */
++	      newsym->n.sym->backend_decl = expr3;
++	      e3rhs = gfc_get_expr ();
++	      e3rhs->ts = code->expr3->ts;
++	      e3rhs->rank = code->expr3->rank;
++	      e3rhs->symtree = newsym;
++	      /* Mark the symbol referenced or gfc_trans_assignment will
++		 bug.  */
++	      newsym->n.sym->attr.referenced = 1;
++	      e3rhs->expr_type = EXPR_VARIABLE;
++	      e3rhs->where = code->expr3->where;
++	      /* Set the symbols type, upto it was BT_UNKNOWN.  */
++	      newsym->n.sym->ts = e3rhs->ts;
++	      /* Check whether the expr3 is array valued.  */
++	      if (e3rhs->rank)
++		{
++		  gfc_array_spec *arr;
++		  arr = gfc_get_array_spec ();
++		  arr->rank = e3rhs->rank;
++		  arr->type = AS_DEFERRED;
++		  /* Set the dimension and pointer attribute for arrays
++		     to be on the safe side.  */
++		  newsym->n.sym->attr.dimension = 1;
++		  newsym->n.sym->attr.pointer = 1;
++		  newsym->n.sym->as = arr;
++		  gfc_add_full_array_ref (e3rhs, arr);
++		}
++	      else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
++		newsym->n.sym->attr.pointer = 1;
++	      /* The string length is known to.  Set it for char arrays.  */
++	      if (e3rhs->ts.type == BT_CHARACTER)
++		newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
++	      gfc_commit_symbol (newsym->n.sym);
++	    }
++	  else
++	    e3rhs = gfc_copy_expr (code->expr3);
+ 	}
+       gcc_assert (expr3_esize);
+       expr3_esize = fold_convert (sizetype, expr3_esize);
+@@ -5335,6 +5639,7 @@
+ 	  expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
+ 					 TREE_TYPE (se_sz.expr),
+ 					 tmp, se_sz.expr);
++	  def_str_len = gfc_evaluate_now (se_sz.expr, &block);
+ 	}
+     }
+ 
+@@ -5386,6 +5691,17 @@
+ 
+       se.want_pointer = 1;
+       se.descriptor_only = 1;
++
++      if (expr->ts.type == BT_CHARACTER
++	  && expr->ts.deferred
++	  && TREE_CODE (expr->ts.u.cl->backend_decl) == VAR_DECL
++	  && def_str_len != NULL_TREE)
++	{
++	  tmp = expr->ts.u.cl->backend_decl;
++	  gfc_add_modify (&block, tmp,
++			  fold_convert (TREE_TYPE (tmp), def_str_len));
++	}
++
+       gfc_conv_expr (&se, expr);
+       if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
+ 	/* se.string_length now stores the .string_length variable of expr
+@@ -5615,7 +5931,6 @@
+ 	{
+ 	  /* Initialization via SOURCE block
+ 	     (or static default initializer).  */
+-	  gfc_expr *rhs = gfc_copy_expr (code->expr3);
+ 	  if (expr3 != NULL_TREE
+ 	      && ((POINTER_TYPE_P (TREE_TYPE (expr3))
+ 		   && TREE_CODE (expr3) != POINTER_PLUS_EXPR)
+@@ -5629,25 +5944,13 @@
+ 	      tmp = gfc_copy_class_to_class (expr3, to,
+ 					     nelems, upoly_expr);
+ 	    }
+-	  else if (code->expr3->ts.type == BT_CHARACTER
+-		   && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
+-	    {
+-	      tmp = INDIRECT_REF_P (se.expr) ?
+-			se.expr :
+-			build_fold_indirect_ref_loc (input_location,
+-						     se.expr);
+-	      gfc_trans_string_copy (&block, al_len, tmp,
+-				     code->expr3->ts.kind,
+-				     expr3_len, expr3,
+-				     code->expr3->ts.kind);
+-	      tmp = NULL_TREE;
+-	    }
+ 	  else if (al->expr->ts.type == BT_CLASS)
+ 	    {
+ 	      gfc_actual_arglist *actual, *last_arg;
+ 	      gfc_expr *ppc;
+ 	      gfc_code *ppc_code;
+ 	      gfc_ref *ref, *dataref;
++	      gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
+ 
+ 	      /* Do a polymorphic deep copy.  */
+ 	      actual = gfc_get_actual_arglist ();
+@@ -5759,6 +6062,8 @@
+ 					 void_type_node, tmp, extcopy, stdcopy);
+ 		}
+ 	      gfc_free_statements (ppc_code);
++	      if (rhs != e3rhs)
++		gfc_free_expr (rhs);
+ 	    }
+ 	  else
+ 	    {
+@@ -5767,10 +6072,9 @@
+ 	      int realloc_lhs = flag_realloc_lhs;
+ 	      flag_realloc_lhs = 0;
+ 	      tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
+-					  rhs, false, false);
++					  e3rhs, false, false);
+ 	      flag_realloc_lhs = realloc_lhs;
+ 	    }
+-	  gfc_free_expr (rhs);
+ 	  gfc_add_expr_to_block (&block, tmp);
+ 	}
+      else if (code->expr3 && code->expr3->mold
+@@ -5788,6 +6092,15 @@
+        gfc_free_expr (expr);
+     } // for-loop
+ 
++  if (e3rhs)
++    {
++      if (newsym)
++	{
++	  gfc_free_symbol (newsym->n.sym);
++	  XDELETE (newsym);
++	}
++      gfc_free_expr (e3rhs);
++    }
+   /* STAT.  */
+   if (code->expr1)
+     {
+--- a/gcc/fortran/trans-stmt.h	2015-01-15 21:11:12.000000000 +0100
++++ b/gcc/fortran/trans-stmt.h	2016-02-16 15:44:29.787760247 +0100
+@@ -55,6 +55,7 @@
+ tree gfc_trans_select (gfc_code *);
+ tree gfc_trans_sync (gfc_code *, gfc_exec_op);
+ tree gfc_trans_lock_unlock (gfc_code *, gfc_exec_op);
++tree gfc_trans_event_post_wait (gfc_code *, gfc_exec_op);
+ tree gfc_trans_forall (gfc_code *);
+ tree gfc_trans_where (gfc_code *);
+ tree gfc_trans_allocate (gfc_code *);
+--- a/gcc/fortran/trans-types.c	2015-11-24 21:40:10.000000000 +0100
++++ b/gcc/fortran/trans-types.c	2016-02-16 15:44:29.787760247 +0100
+@@ -1,5 +1,5 @@
+ /* Backend support for Fortran 95 basic types and derived types.
+-   Copyright (C) 2002-2015 Free Software Foundation, Inc.
++   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+    Contributed by Paul Brook <paul at nowt.org>
+    and Steven Bosscher <s.bosscher at student.tudelft.nl>
+ 
+@@ -2383,6 +2383,11 @@
+ 	  && derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE))
+     return ptr_type_node;
+ 
++  if (flag_coarray != GFC_FCOARRAY_LIB
++      && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
++      && derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
++    return gfc_get_int_type (gfc_default_integer_kind);
++
+   if (derived && derived->attr.flavor == FL_PROCEDURE
+       && derived->attr.generic)
+     derived = gfc_find_dt_in_generic (derived);
+--- a/gcc/genpreds.c	2015-01-09 21:18:42.000000000 +0100
++++ b/gcc/genpreds.c	2016-02-16 15:23:33.706553265 +0100
+@@ -640,12 +640,14 @@
+   const char *regclass;  /* for register constraints */
+   rtx exp;               /* for other constraints */
+   unsigned int lineno;   /* line of definition */
+-  unsigned int is_register  : 1;
+-  unsigned int is_const_int : 1;
+-  unsigned int is_const_dbl : 1;
+-  unsigned int is_extra     : 1;
+-  unsigned int is_memory    : 1;
+-  unsigned int is_address   : 1;
++  unsigned int is_register	: 1;
++  unsigned int is_const_int	: 1;
++  unsigned int is_const_dbl	: 1;
++  unsigned int is_extra		: 1;
++  unsigned int is_memory	: 1;
++  unsigned int is_address	: 1;
++  unsigned int maybe_allows_reg : 1;
++  unsigned int maybe_allows_mem : 1;
+ };
+ 
+ /* Overview of all constraints beginning with a given letter.  */
+@@ -691,6 +693,9 @@
+ static unsigned int const_int_start, const_int_end;
+ static unsigned int memory_start, memory_end;
+ static unsigned int address_start, address_end;
++static unsigned int maybe_allows_none_start, maybe_allows_none_end;
++static unsigned int maybe_allows_reg_start, maybe_allows_reg_end;
++static unsigned int maybe_allows_mem_start, maybe_allows_mem_end;
+ 
+ /* Convert NAME, which contains angle brackets and/or underscores, to
+    a string that can be used as part of a C identifier.  The string
+@@ -711,6 +716,34 @@
+   return XOBFINISH (rtl_obstack, const char *);
+ }
+ 
++/* Return a bitmask, bit 1 if EXP maybe allows a REG/SUBREG, 2 if EXP
++   maybe allows a MEM.  Bits should be clear only when we are sure it
++   will not allow a REG/SUBREG or a MEM.  */
++static int
++compute_maybe_allows (rtx exp)
++{
++  switch (GET_CODE (exp))
++    {
++    case IF_THEN_ELSE:
++      /* Conservative answer is like IOR, of the THEN and ELSE branches.  */
++      return compute_maybe_allows (XEXP (exp, 1))
++	     | compute_maybe_allows (XEXP (exp, 2));
++    case AND:
++      return compute_maybe_allows (XEXP (exp, 0))
++	     & compute_maybe_allows (XEXP (exp, 1));
++    case IOR:
++      return compute_maybe_allows (XEXP (exp, 0))
++	     | compute_maybe_allows (XEXP (exp, 1));
++    case MATCH_CODE:
++      if (*XSTR (exp, 1) == '\0')
++	return (strstr (XSTR (exp, 0), "reg") != NULL ? 1 : 0)
++	       | (strstr (XSTR (exp, 0), "mem") != NULL ? 2 : 0);
++      /* FALLTHRU */
++    default:
++      return 3;
++    }
++}
++
+ /* Add one constraint, of any sort, to the tables.  NAME is its name;
+    REGCLASS is the register class, if any; EXP is the expression to
+    test, if any;  IS_MEMORY and IS_ADDRESS indicate memory and address
+@@ -866,6 +899,11 @@
+   c->is_extra = !(regclass || is_const_int || is_const_dbl);
+   c->is_memory = is_memory;
+   c->is_address = is_address;
++  int maybe_allows = 3;
++  if (exp)
++    maybe_allows = compute_maybe_allows (exp);
++  c->maybe_allows_reg = (maybe_allows & 1) != 0;
++  c->maybe_allows_mem = (maybe_allows & 2) != 0;
+ 
+   c->next_this_letter = *slot;
+   *slot = c;
+@@ -940,8 +978,30 @@
+       enum_order[next++] = c;
+   address_end = next;
+ 
++  maybe_allows_none_start = next;
++  FOR_ALL_CONSTRAINTS (c)
++    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
++	&& !c->maybe_allows_reg && !c->maybe_allows_mem)
++      enum_order[next++] = c;
++  maybe_allows_none_end = next;
++
++  maybe_allows_reg_start = next;
++  FOR_ALL_CONSTRAINTS (c)
++    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
++	&& c->maybe_allows_reg && !c->maybe_allows_mem)
++      enum_order[next++] = c;
++  maybe_allows_reg_end = next;
++
++  maybe_allows_mem_start = next;
++  FOR_ALL_CONSTRAINTS (c)
++    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
++	&& !c->maybe_allows_reg && c->maybe_allows_mem)
++      enum_order[next++] = c;
++  maybe_allows_mem_end = next;
++
+   FOR_ALL_CONSTRAINTS (c)
+-    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address)
++    if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address
++	&& c->maybe_allows_reg && c->maybe_allows_mem)
+       enum_order[next++] = c;
+   gcc_assert (next == num_constraints);
+ }
+@@ -1229,6 +1289,41 @@
+ 	    "}\n\n", name);
+ }
+ 
++/* Write a definition for insn_extra_constraint_allows_reg_mem function.  */
++static void
++write_allows_reg_mem_function (void)
++{
++  printf ("static inline void\n"
++	  "insn_extra_constraint_allows_reg_mem (enum constraint_num c,\n"
++	  "\t\t\t\t      bool *allows_reg, bool *allows_mem)\n"
++	  "{\n");
++  if (maybe_allows_none_start != maybe_allows_none_end)
++    printf ("  if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n"
++	    "    return;\n",
++	    enum_order[maybe_allows_none_start]->c_name,
++	    enum_order[maybe_allows_none_end - 1]->c_name);
++  if (maybe_allows_reg_start != maybe_allows_reg_end)
++    printf ("  if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n"
++	    "    {\n"
++	    "      *allows_reg = true;\n"
++	    "      return;\n"
++	    "    }\n",
++	    enum_order[maybe_allows_reg_start]->c_name,
++	    enum_order[maybe_allows_reg_end - 1]->c_name);
++  if (maybe_allows_mem_start != maybe_allows_mem_end)
++    printf ("  if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n"
++	    "    {\n"
++	    "      *allows_mem = true;\n"
++	    "      return;\n"
++	    "    }\n",
++	    enum_order[maybe_allows_mem_start]->c_name,
++	    enum_order[maybe_allows_mem_end - 1]->c_name);
++  printf ("  (void) c;\n"
++	  "  *allows_reg = true;\n"
++	  "  *allows_mem = true;\n"
++	  "}\n\n");
++}
++
+ /* VEC is a list of key/value pairs, with the keys being lower bounds
+    of a range.  Output a decision tree that handles the keys covered by
+    [VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s.
+@@ -1326,6 +1421,7 @@
+ 			    memory_start, memory_end);
+       write_range_function ("insn_extra_address_constraint",
+ 			    address_start, address_end);
++      write_allows_reg_mem_function ();
+ 
+       if (constraint_max_namelen > 1)
+         {
+--- a/gcc/gimple.c	2015-02-04 21:28:49.000000000 +0100
++++ b/gcc/gimple.c	2016-02-16 15:43:57.774213147 +0100
+@@ -1953,6 +1953,11 @@
+ 				       && TYPE_OVERFLOW_TRAPS (t)),
+ 				      div));
+ 
++    case GIMPLE_COND:
++      t = TREE_TYPE (gimple_cond_lhs (s));
++      return operation_could_trap_p (gimple_cond_code (s),
++				     FLOAT_TYPE_P (t), false, NULL_TREE);
++
+     default:
+       break;
+     }
+--- a/gcc/gimple-expr.c	2015-01-09 21:18:42.000000000 +0100
++++ b/gcc/gimple-expr.c	2016-02-16 15:42:03.476284633 +0100
+@@ -387,6 +387,11 @@
+   TREE_USED (copy) = 1;
+   DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
+   DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);
++  if (DECL_USER_ALIGN (var))
++    {
++      DECL_ALIGN (copy) = DECL_ALIGN (var);
++      DECL_USER_ALIGN (copy) = 1;
++    }
+ 
+   return copy;
+ }
+--- a/gcc/gimple-ssa-strength-reduction.c	2015-01-15 14:28:42.000000000 +0100
++++ b/gcc/gimple-ssa-strength-reduction.c	2016-02-16 15:26:35.604094164 +0100
+@@ -2267,7 +2267,7 @@
+   slsr_cand_t basis = lookup_cand (c->basis);
+   int nargs = gimple_phi_num_args (from_phi);
+   basic_block phi_bb = gimple_bb (from_phi);
+-  slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (from_phi));
++  slsr_cand_t phi_cand = *stmt_cand_map->get (from_phi);
+   phi_args.create (nargs);
+ 
+   /* Process each argument of the existing phi that represents
+@@ -2376,7 +2376,7 @@
+ {
+   unsigned i;
+   int cost = 0;
+-  slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
++  slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
+ 
+   /* If we work our way back to a phi that isn't dominated by the hidden
+      basis, this isn't a candidate for replacement.  Indicate this by
+@@ -2587,7 +2587,7 @@
+ record_phi_increments (slsr_cand_t basis, gimple phi)
+ {
+   unsigned i;
+-  slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
++  slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
+   
+   for (i = 0; i < gimple_phi_num_args (phi); i++)
+     {
+@@ -2658,7 +2658,7 @@
+   unsigned i;
+   int cost = 0;
+   slsr_cand_t basis = lookup_cand (c->basis);
+-  slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
++  slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
+ 
+   for (i = 0; i < gimple_phi_num_args (phi); i++)
+     {
+@@ -3002,7 +3002,7 @@
+ {
+   unsigned i;
+   slsr_cand_t basis = lookup_cand (c->basis);
+-  slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
++  slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
+ 
+   for (i = 0; i < gimple_phi_num_args (phi); i++)
+     {
+@@ -3212,7 +3212,7 @@
+ {
+   unsigned i;
+   slsr_cand_t basis = lookup_cand (c->basis);
+-  slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
++  slsr_cand_t phi_cand = *stmt_cand_map->get (phi);
+ 
+   for (i = 0; i < gimple_phi_num_args (phi); i++)
+     {
+--- a/gcc/gimplify.c	2015-09-10 09:41:34.000000000 +0200
++++ b/gcc/gimplify.c	2016-02-16 15:42:10.088395040 +0100
+@@ -5208,12 +5208,38 @@
+ 	    TREE_VALUE (link) = error_mark_node;
+ 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+ 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
++	  if (tret != GS_ERROR)
++	    {
++	      /* Unlike output operands, memory inputs are not guaranteed
++		 to be lvalues by the FE, and while the expressions are
++		 marked addressable there, if it is e.g. a statement
++		 expression, temporaries in it might not end up being
++		 addressable.  They might be already used in the IL and thus
++		 it is too late to make them addressable now though.  */
++	      tree x = TREE_VALUE (link);
++	      while (handled_component_p (x))
++		x = TREE_OPERAND (x, 0);
++	      if (TREE_CODE (x) == MEM_REF
++		  && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
++		x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
++	      if ((TREE_CODE (x) == VAR_DECL
++		   || TREE_CODE (x) == PARM_DECL
++		   || TREE_CODE (x) == RESULT_DECL)
++		  && !TREE_ADDRESSABLE (x)
++		  && is_gimple_reg (x))
++		{
++		  warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
++					       input_location), 0,
++			      "memory input %d is not directly addressable",
++			      i);
++		  prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
++		}
++	    }
+ 	  mark_addressable (TREE_VALUE (link));
+ 	  if (tret == GS_ERROR)
+ 	    {
+-	      if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
+-	        input_location = EXPR_LOCATION (TREE_VALUE (link));
+-	      error ("memory input %d is not directly addressable", i);
++	      error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
++			"memory input %d is not directly addressable", i);
+ 	      ret = tret;
+ 	    }
+ 	}
+--- a/gcc/ifcvt.c	2015-11-19 09:53:52.000000000 +0100
++++ b/gcc/ifcvt.c	2016-02-16 15:42:01.325248748 +0100
+@@ -2152,45 +2152,22 @@
+      Note that these rtx constants are known to be CONST_INT, and
+      therefore imply integer comparisons.
+      The one_cmpl case is more complicated, as we want to handle
+-     only x < 0 ? ~x : x or x >= 0 ? ~x : x but not
+-     x <= 0 ? ~x : x or x > 0 ? ~x : x, as the latter two
+-     have different result for x == 0.  */
++     only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x)
++     and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x),
++     but not other cases (x > -1 is equivalent of x >= 0).  */
+   if (c == constm1_rtx && GET_CODE (cond) == GT)
+-    {
+-      if (one_cmpl && negate)
+-	return FALSE;
+-    }
++    ;
+   else if (c == const1_rtx && GET_CODE (cond) == LT)
+     {
+-      if (one_cmpl && !negate)
++      if (one_cmpl)
+ 	return FALSE;
+     }
+   else if (c == CONST0_RTX (GET_MODE (b)))
+     {
+-      if (one_cmpl)
+-	switch (GET_CODE (cond))
+-	  {
+-	  case GT:
+-	    if (!negate)
+-	      return FALSE;
+-	    break;
+-	  case GE:
+-	    /* >= 0 is the same case as above > -1.  */
+-	    if (negate)
+-	      return FALSE;
+-	    break;
+-	  case LT:
+-	    if (negate)
+-	      return FALSE;
+-	    break;
+-	  case LE:
+-	    /* <= 0 is the same case as above < 1.  */
+-	    if (!negate)
+-	      return FALSE;
+-	    break;
+-	  default:
+-	    return FALSE;
+-	  }
++      if (one_cmpl
++	  && GET_CODE (cond) != GE
++	  && GET_CODE (cond) != LT)
++	return FALSE;
+     }
+   else
+     return FALSE;
+@@ -3847,8 +3824,11 @@
+     return FALSE;
+ 
+   /* If the conditional jump is more than just a conditional jump, then
+-     we can not do if-conversion on this block.  */
+-  if (! onlyjump_p (jump))
++     we can not do if-conversion on this block.  Give up for returnjump_p,
++     changing a conditional return followed by unconditional trap for
++     conditional trap followed by unconditional return is likely not
++     beneficial and harder to handle.  */
++  if (! onlyjump_p (jump) || returnjump_p (jump))
+     return FALSE;
+ 
+   /* We must be comparing objects whose modes imply the size.  */
+--- a/gcc/ipa-cp.c	2015-04-06 17:58:37.000000000 +0200
++++ b/gcc/ipa-cp.c	2016-02-16 15:10:15.351360293 +0100
+@@ -1787,6 +1787,18 @@
+   return ret;
+ }
+ 
++/* Return true if on the way cfrom CS->caller to the final (non-alias and
++   non-thunk) destination, the call passes through a thunk.  */
++
++static bool
++call_passes_through_thunk_p (cgraph_edge *cs)
++{
++  cgraph_node *alias_or_thunk = cs->callee;
++  while (alias_or_thunk->alias)
++    alias_or_thunk = alias_or_thunk->get_alias_target ();
++  return alias_or_thunk->thunk.thunk_p;
++}
++
+ /* Propagate constants from the caller to the callee of CS.  INFO describes the
+    caller.  */
+ 
+@@ -1795,7 +1807,7 @@
+ {
+   struct ipa_node_params *callee_info;
+   enum availability availability;
+-  struct cgraph_node *callee, *alias_or_thunk;
++  cgraph_node *callee;
+   struct ipa_edge_args *args;
+   bool ret = false;
+   int i, args_count, parms_count;
+@@ -1833,10 +1845,7 @@
+   /* If this call goes through a thunk we must not propagate to the first (0th)
+      parameter.  However, we might need to uncover a thunk from below a series
+      of aliases first.  */
+-  alias_or_thunk = cs->callee;
+-  while (alias_or_thunk->alias)
+-    alias_or_thunk = alias_or_thunk->get_alias_target ();
+-  if (alias_or_thunk->thunk.thunk_p)
++  if (call_passes_through_thunk_p (cs))
+     {
+       ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
+ 							       0));
+@@ -3404,7 +3413,11 @@
+ 	  struct ipa_jump_func *jump_func;
+ 	  tree t;
+ 
+-          if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
++          if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
++	      || (i == 0
++		  && call_passes_through_thunk_p (cs))
++	      || (!cs->callee->instrumentation_clone
++		  && cs->callee->function_symbol ()->instrumentation_clone))
+             {
+               newval = NULL_TREE;
+               break;
+--- a/gcc/ipa-devirt.c	2015-07-27 21:53:53.000000000 +0200
++++ b/gcc/ipa-devirt.c	2016-02-16 15:06:04.485336932 +0100
+@@ -1536,6 +1536,7 @@
+ 	break;
+       }
+     case VOID_TYPE:
++    case NULLPTR_TYPE:
+       break;
+ 
+     default:
+--- a/gcc/ipa-icf.c	2015-11-23 14:58:40.000000000 +0100
++++ b/gcc/ipa-icf.c	2016-02-16 15:05:10.672319553 +0100
+@@ -444,7 +444,7 @@
+ sem_function::param_used_p (unsigned int i)
+ {
+   if (ipa_node_params_sum == NULL)
+-    return false;
++    return true;
+ 
+   struct ipa_node_params *parms_info = IPA_NODE_REF (get_node ());
+ 
+--- a/gcc/lra-remat.c	2015-11-06 18:33:01.000000000 +0100
++++ b/gcc/lra-remat.c	2016-02-16 15:33:47.218413468 +0100
+@@ -112,6 +112,9 @@
+ /* Bitmap used for different calculations.  */
+ static bitmap_head temp_bitmap;
+ 
++/* Registers accessed via subreg_p.  */
++static bitmap_head subreg_regs;
++
+ typedef struct cand *cand_t;
+ typedef const struct cand *const_cand_t;
+ 
+@@ -418,30 +421,30 @@
+     return -1;
+   /* First find a pseudo which can be rematerialized.  */
+   for (reg = id->regs; reg != NULL; reg = reg->next)
+-    /* True FRAME_POINTER_NEEDED might be because we can not follow
+-       changing sp offsets, e.g. alloca is used.  If the insn contains
+-       stack pointer in such case, we can not rematerialize it as we
+-       can not know sp offset at a rematerialization place.  */
+-    if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed)
+-      return -1;
+-    else if (reg->type == OP_OUT && ! reg->subreg_p
+-	     && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
+-      {
+-	/* We permits only one spilled reg.  */
+-	if (found_reg != NULL)
+-	  return -1;
+-	found_reg = reg;
+-      }
+-    /* IRA calculates conflicts separately for subregs of two words
+-       pseudo.  Even if the pseudo lives, e.g. one its subreg can be
+-       used lately, another subreg hard register can be already used
+-       for something else.  In such case, it is not safe to
+-       rematerialize the insn.  */
+-    else if (reg->type == OP_IN && reg->subreg_p
+-	     && reg->regno >= FIRST_PSEUDO_REGISTER
+-	     && (GET_MODE_SIZE (PSEUDO_REGNO_MODE (reg->regno))
+-		 == 2 * UNITS_PER_WORD))
+-      return -1;
++    {
++      /* True FRAME_POINTER_NEEDED might be because we can not follow
++	 changing sp offsets, e.g. alloca is used.  If the insn contains
++	 stack pointer in such case, we can not rematerialize it as we
++	 can not know sp offset at a rematerialization place.  */
++      if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed)
++	return -1;
++      else if (reg->type == OP_OUT && ! reg->subreg_p
++	       && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
++	{
++	  /* We permits only one spilled reg.  */
++	  if (found_reg != NULL)
++	    return -1;
++	  found_reg = reg;
++        }
++      /* IRA calculates conflicts separately for subregs of two words
++	 pseudo.  Even if the pseudo lives, e.g. one its subreg can be
++	 used lately, another subreg hard register can be already used
++	 for something else.  In such case, it is not safe to
++	 rematerialize the insn.  */
++      if (reg->regno >= FIRST_PSEUDO_REGISTER
++	  && bitmap_bit_p (&subreg_regs, reg->regno))
++	return -1;
++    }
+   if (found_reg == NULL)
+     return -1;
+   if (found_reg->regno < FIRST_PSEUDO_REGISTER)
+@@ -668,6 +671,9 @@
+       lra_dump_bitmap_with_title ("avout cands in BB",
+ 				  &get_remat_bb_data (bb)->avout_cands, bb->index);
+     }
++  fprintf (lra_dump_file, "subreg regs:");
++  dump_regset (&subreg_regs, lra_dump_file);
++  putc ('\n', lra_dump_file);
+ }
+ 
+ /* Free all BB data.  */
+@@ -692,21 +698,24 @@
+ 
+ 
+ 
+-/* Update changed_regs and dead_regs of BB from INSN.  */
++/* Update changed_regs, dead_regs, subreg_regs of BB from INSN.  */
+ static void
+ set_bb_regs (basic_block bb, rtx_insn *insn)
+ {
+   lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
++  remat_bb_data_t bb_info = get_remat_bb_data (bb);
+   struct lra_insn_reg *reg;
+ 
+   for (reg = id->regs; reg != NULL; reg = reg->next)
+-    if (reg->type != OP_IN)
+-      bitmap_set_bit (&get_remat_bb_data (bb)->changed_regs, reg->regno);
+-    else
+-      {
+-	if (find_regno_note (insn, REG_DEAD, (unsigned) reg->regno) != NULL)
+-	  bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs, reg->regno);
+-      }
++    {
++      unsigned regno = reg->regno;
++      if (reg->type != OP_IN)
++        bitmap_set_bit (&bb_info->changed_regs, regno);
++      else if (find_regno_note (insn, REG_DEAD, regno) != NULL)
++	bitmap_set_bit (&bb_info->dead_regs, regno);
++      if (regno >= FIRST_PSEUDO_REGISTER && reg->subreg_p)
++	bitmap_set_bit (&subreg_regs, regno);
++    }
+   if (CALL_P (insn))
+     for (int i = 0; i < call_used_regs_arr_len; i++)
+       bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs,
+@@ -722,7 +731,7 @@
+ 
+   FOR_EACH_BB_FN (bb, cfun)
+     FOR_BB_INSNS (bb, insn)
+-      if (INSN_P (insn))
++      if (NONDEBUG_INSN_P (insn))
+ 	set_bb_regs (bb, insn);
+ }
+ 
+@@ -1321,10 +1330,11 @@
+     if (call_used_regs[i])
+       call_used_regs_arr[call_used_regs_arr_len++] = i;
+   initiate_cand_table ();
+-  create_cands ();
+   create_remat_bb_data ();
+   bitmap_initialize (&temp_bitmap, &reg_obstack);
++  bitmap_initialize (&subreg_regs, &reg_obstack);
+   calculate_local_reg_remat_bb_data ();
++  create_cands ();
+   calculate_livein_cands ();
+   calculate_gen_cands ();
+   bitmap_initialize (&all_blocks, &reg_obstack);
+@@ -1335,6 +1345,7 @@
+   result = do_remat ();
+   all_cands.release ();
+   bitmap_clear (&temp_bitmap);
++  bitmap_clear (&subreg_regs);
+   finish_remat_bb_data ();
+   finish_cand_table ();
+   bitmap_clear (&all_blocks);
+--- a/gcc/match.pd	2015-06-03 09:39:06.000000000 +0200
++++ b/gcc/match.pd	2016-02-16 15:28:40.239506131 +0100
+@@ -382,12 +382,15 @@
+   (bit_not (bit_not @0))
+   @0)
+ 
++/* Disable on GENERIC because of PR68513.  */
++#if GIMPLE
+ /* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */
+ (simplify
+   (bit_ior:c (bit_and:c at 3 @0 (bit_not @2)) (bit_and:c at 4 @1 @2))
+   (if ((TREE_CODE (@3) != SSA_NAME || has_single_use (@3))
+ 	&& (TREE_CODE (@4) != SSA_NAME || has_single_use (@4)))
+    (bit_xor (bit_and (bit_xor @0 @1) @2) @0)))
++#endif
+ 
+ 
+ /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)).  */
+--- a/gcc/shrink-wrap.c	2015-01-15 14:28:42.000000000 +0100
++++ b/gcc/shrink-wrap.c	2016-02-16 15:42:08.881374875 +0100
+@@ -79,6 +79,7 @@
+ #include "shrink-wrap.h"
+ #include "regcprop.h"
+ #include "rtl-iter.h"
++#include "valtrack.h"
+ 
+ #ifdef HAVE_simple_return
+ 
+@@ -191,7 +192,8 @@
+ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
+ 			   const HARD_REG_SET uses,
+ 			   const HARD_REG_SET defs,
+-			   bool *split_p)
++			   bool *split_p,
++			   struct dead_debug_local *debug)
+ {
+   rtx set, src, dest;
+   bitmap live_out, live_in, bb_uses, bb_defs;
+@@ -200,6 +202,8 @@
+   unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
+   basic_block next_block;
+   edge live_edge;
++  rtx_insn *dinsn;
++  df_ref def;
+ 
+   /* Look for a simple register assignment.  We don't use single_set here
+      because we can't deal with any CLOBBERs, USEs, or REG_UNUSED secondary
+@@ -344,6 +348,20 @@
+      move it as far as we can.  */
+   do
+     {
++      if (MAY_HAVE_DEBUG_INSNS)
++	{
++	  FOR_BB_INSNS_REVERSE (bb, dinsn)
++	    if (DEBUG_INSN_P (dinsn))
++	      {
++		df_ref use;
++		FOR_EACH_INSN_USE (use, dinsn)
++		  if (refers_to_regno_p (dregno, end_dregno,
++					 DF_REF_REG (use), (rtx *) NULL))
++		    dead_debug_add (debug, use, DF_REF_REGNO (use));
++	      }
++	    else if (dinsn == insn)
++	      break;
++	}
+       live_out = df_get_live_out (bb);
+       live_in = df_get_live_in (next_block);
+       bb = next_block;
+@@ -426,6 +444,12 @@
+ 	SET_REGNO_REG_SET (bb_uses, i);
+     }
+ 
++  /* Insert debug temps for dead REGs used in subsequent debug insns.  */
++  if (debug->used && !bitmap_empty_p (debug->used))
++    FOR_EACH_INSN_DEF (def, insn)
++      dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn,
++			      DEBUG_TEMP_BEFORE_WITH_VALUE);
++
+   emit_insn_after (PATTERN (insn), bb_note (bb));
+   delete_insn (insn);
+   return true;
+@@ -446,6 +470,8 @@
+   HARD_REG_SET uses, defs;
+   df_ref def, use;
+   bool split_p = false;
++  unsigned int i;
++  struct dead_debug_local debug;
+ 
+   if (JUMP_P (BB_END (entry_block)))
+     {
+@@ -456,19 +482,22 @@
+       copyprop_hardreg_forward_bb_without_debug_insn (entry_block);
+     }
+ 
++  dead_debug_local_init (&debug, NULL, NULL);
+   CLEAR_HARD_REG_SET (uses);
+   CLEAR_HARD_REG_SET (defs);
++
+   FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr)
+     if (NONDEBUG_INSN_P (insn)
+ 	&& !move_insn_for_shrink_wrap (entry_block, insn, uses, defs,
+-				       &split_p))
++				       &split_p, &debug))
+       {
+ 	/* Add all defined registers to DEFs.  */
+ 	FOR_EACH_INSN_DEF (def, insn)
+ 	  {
+ 	    x = DF_REF_REG (def);
+ 	    if (REG_P (x) && HARD_REGISTER_P (x))
+-	      SET_HARD_REG_BIT (defs, REGNO (x));
++	      for (i = REGNO (x); i < END_REGNO (x); i++)
++		SET_HARD_REG_BIT (defs, i);
+ 	  }
+ 
+ 	/* Add all used registers to USESs.  */
+@@ -476,9 +505,12 @@
+ 	  {
+ 	    x = DF_REF_REG (use);
+ 	    if (REG_P (x) && HARD_REGISTER_P (x))
+-	      SET_HARD_REG_BIT (uses, REGNO (x));
++	      for (i = REGNO (x); i < END_REGNO (x); i++)
++		SET_HARD_REG_BIT (uses, i);
+ 	  }
+       }
++
++  dead_debug_local_finish (&debug, NULL);
+ }
+ 
+ /* Create a copy of BB instructions and insert at BEFORE.  Redirect
+--- a/gcc/stmt.c	2015-02-13 15:42:30.000000000 +0100
++++ b/gcc/stmt.c	2016-02-16 15:23:33.706553265 +0100
+@@ -342,13 +342,7 @@
+ 	else if (insn_extra_memory_constraint (cn))
+ 	  *allows_mem = true;
+ 	else
+-	  {
+-	    /* Otherwise we can't assume anything about the nature of
+-	       the constraint except that it isn't purely registers.
+-	       Treat it like "g" and hope for the best.  */
+-	    *allows_reg = true;
+-	    *allows_mem = true;
+-	  }
++	  insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
+ 	break;
+       }
+ 
+@@ -465,13 +459,7 @@
+ 	else if (insn_extra_memory_constraint (cn))
+ 	  *allows_mem = true;
+ 	else
+-	  {
+-	    /* Otherwise we can't assume anything about the nature of
+-	       the constraint except that it isn't purely registers.
+-	       Treat it like "g" and hope for the best.  */
+-	    *allows_reg = true;
+-	    *allows_mem = true;
+-	  }
++	  insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
+ 	break;
+       }
+ 
+--- a/gcc/tree.c	2015-10-27 17:55:03.000000000 +0100
++++ b/gcc/tree.c	2016-02-16 15:15:16.624657302 +0100
+@@ -1221,11 +1221,9 @@
+ get_int_cst_ext_nunits (tree type, const wide_int &cst)
+ {
+   gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type));
+-  /* We need an extra zero HWI if CST is an unsigned integer with its
+-     upper bit set, and if CST occupies a whole number of HWIs.  */
+-  if (TYPE_UNSIGNED (type)
+-      && wi::neg_p (cst)
+-      && (cst.get_precision () % HOST_BITS_PER_WIDE_INT) == 0)
++  /* We need extra HWIs if CST is an unsigned integer with its
++     upper bit set.  */
++  if (TYPE_UNSIGNED (type) && wi::neg_p (cst))
+     return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1;
+   return cst.get_len ();
+ }
+@@ -1242,7 +1240,8 @@
+   if (len < ext_len)
+     {
+       --ext_len;
+-      TREE_INT_CST_ELT (nt, ext_len) = 0;
++      TREE_INT_CST_ELT (nt, ext_len)
++	= zext_hwi (-1, cst.get_precision () % HOST_BITS_PER_WIDE_INT);
+       for (unsigned int i = len; i < ext_len; ++i)
+ 	TREE_INT_CST_ELT (nt, i) = -1;
+     }
+--- a/gcc/tree-chrec.c	2015-03-20 13:39:32.000000000 +0100
++++ b/gcc/tree-chrec.c	2016-02-16 15:43:57.776213181 +0100
+@@ -746,12 +746,12 @@
+ 	/* There is no evolution in this loop.  */
+ 	return initial_condition (chrec);
+ 
++      else if (flow_loop_nested_p (loop, chloop))
++	return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
++							loop_num);
++
+       else
+-	{
+-	  gcc_assert (flow_loop_nested_p (loop, chloop));
+-	  return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
+-							  loop_num);
+-	}
++	return chrec_dont_know;
+ 
+     default:
+       return chrec;
+--- a/gcc/tree-data-ref.c	2015-06-03 09:39:06.000000000 +0200
++++ b/gcc/tree-data-ref.c	2016-02-16 15:31:27.080721566 +0100
+@@ -1534,13 +1534,14 @@
+   /* The case where the references are exactly the same.  */
+   if (operand_equal_p (DR_REF (a), DR_REF (b), 0))
+     {
+-     if (loop_nest.exists ()
+-        && !object_address_invariant_in_loop_p (loop_nest[0],
+-       					        DR_BASE_OBJECT (a)))
+-      {
+-        DDR_ARE_DEPENDENT (res) = chrec_dont_know;
+-        return res;
+-      }
++      if ((loop_nest.exists ()
++	   && !object_address_invariant_in_loop_p (loop_nest[0],
++						   DR_BASE_OBJECT (a)))
++	  || DR_NUM_DIMENSIONS (a) == 0)
++	{
++	  DDR_ARE_DEPENDENT (res) = chrec_dont_know;
++	  return res;
++	}
+       DDR_AFFINE_P (res) = true;
+       DDR_ARE_DEPENDENT (res) = NULL_TREE;
+       DDR_SUBSCRIPTS (res).create (DR_NUM_DIMENSIONS (a));
+@@ -1572,9 +1573,9 @@
+   /* If the base of the object is not invariant in the loop nest, we cannot
+      analyze it.  TODO -- in fact, it would suffice to record that there may
+      be arbitrary dependences in the loops where the base object varies.  */
+-  if (loop_nest.exists ()
+-      && !object_address_invariant_in_loop_p (loop_nest[0],
+-     					      DR_BASE_OBJECT (a)))
++  if ((loop_nest.exists ()
++       && !object_address_invariant_in_loop_p (loop_nest[0], DR_BASE_OBJECT (a)))
++      || DR_NUM_DIMENSIONS (a) == 0)
+     {
+       DDR_ARE_DEPENDENT (res) = chrec_dont_know;
+       return res;
+--- a/gcc/tree-parloops.c	2015-03-21 11:14:10.000000000 +0100
++++ b/gcc/tree-parloops.c	2016-02-16 15:30:32.881678443 +0100
+@@ -741,6 +741,7 @@
+     }
+   else if (gimple_clobber_p (stmt))
+     {
++      unlink_stmt_vdef (stmt);
+       stmt = gimple_build_nop ();
+       gsi_replace (gsi, stmt, false);
+       dta.changed = true;
+--- a/gcc/tree-sra.c	2015-10-27 13:23:24.000000000 +0100
++++ b/gcc/tree-sra.c	2016-02-16 15:33:02.984564516 +0100
+@@ -2329,7 +2329,7 @@
+ 
+       if (covered_to < limit)
+ 	hole = true;
+-      if (scalar)
++      if (scalar || !allow_replacements)
+ 	root->grp_total_scalarization = 0;
+     }
+ 
+--- a/gcc/tree-ssa.c	2015-02-06 15:37:59.000000000 +0100
++++ b/gcc/tree-ssa.c	2016-02-16 15:43:57.777213198 +0100
+@@ -1448,7 +1448,8 @@
+               tree lhs = gimple_get_lhs (stmt);
+               if (lhs
+ 		  && TREE_CODE (lhs) != SSA_NAME
+-		  && non_rewritable_lvalue_p (lhs))
++		  && ((code == GIMPLE_CALL && ! DECL_P (lhs))
++		      || non_rewritable_lvalue_p (lhs)))
+ 		{
+ 		  decl = get_base_address (lhs);
+ 		  if (DECL_P (decl))
+--- a/gcc/tree-ssa-loop-ivcanon.c	2015-06-22 16:12:24.000000000 +0200
++++ b/gcc/tree-ssa-loop-ivcanon.c	2016-02-16 15:43:57.776213181 +0100
+@@ -1237,7 +1237,9 @@
+       tree result = gimple_phi_result (phi);
+       tree arg = gimple_phi_arg_def (phi, 0);
+ 
+-      if (gimple_phi_num_args (phi) == 1 && TREE_CODE (arg) == INTEGER_CST)
++      if (! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (result)
++	  && gimple_phi_num_args (phi) == 1
++	  && TREE_CODE (arg) == INTEGER_CST)
+ 	{
+ 	  propagate_into_all_uses (result, arg);
+ 	  gsi_remove (&gsi, true);
+--- a/gcc/tree-ssa-math-opts.c	2015-08-11 09:58:07.000000000 +0200
++++ b/gcc/tree-ssa-math-opts.c	2016-02-16 15:43:57.777213198 +0100
+@@ -2141,6 +2141,8 @@
+ static gimple
+ find_bswap_or_nop (gimple stmt, struct symbolic_number *n, bool *bswap)
+ {
++  unsigned rsize;
++  uint64_t tmpn, mask;
+ /* The number which the find_bswap_or_nop_1 result should match in order
+    to have a full byte swap.  The number is shifted to the right
+    according to the size of the symbolic number before using it.  */
+@@ -2164,24 +2166,38 @@
+ 
+   /* Find real size of result (highest non-zero byte).  */
+   if (n->base_addr)
+-    {
+-      int rsize;
+-      uint64_t tmpn;
+-
+-      for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++);
+-      n->range = rsize;
+-    }
++    for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++);
++  else
++    rsize = n->range;
+ 
+-  /* Zero out the extra bits of N and CMP*.  */
++  /* Zero out the bits corresponding to untouched bytes in original gimple
++     expression.  */
+   if (n->range < (int) sizeof (int64_t))
+     {
+-      uint64_t mask;
+-
+       mask = ((uint64_t) 1 << (n->range * BITS_PER_MARKER)) - 1;
+       cmpxchg >>= (64 / BITS_PER_MARKER - n->range) * BITS_PER_MARKER;
+       cmpnop &= mask;
+     }
+ 
++  /* Zero out the bits corresponding to unused bytes in the result of the
++     gimple expression.  */
++  if (rsize < n->range)
++    {
++      if (BYTES_BIG_ENDIAN)
++	{
++	  mask = ((uint64_t) 1 << (rsize * BITS_PER_MARKER)) - 1;
++	  cmpxchg &= mask;
++	  cmpnop >>= (n->range - rsize) * BITS_PER_MARKER;
++	}
++      else
++	{
++	  mask = ((uint64_t) 1 << (rsize * BITS_PER_MARKER)) - 1;
++	  cmpxchg >>= (n->range - rsize) * BITS_PER_MARKER;
++	  cmpnop &= mask;
++	}
++      n->range = rsize;
++    }
++
+   /* A complete byte swap should make the symbolic number to start with
+      the largest digit in the highest order byte. Unchanged symbolic
+      number indicates a read with same endianness as target architecture.  */
+@@ -2297,6 +2313,8 @@
+       /* Move cur_stmt just before  one of the load of the original
+ 	 to ensure it has the same VUSE.  See PR61517 for what could
+ 	 go wrong.  */
++      if (gimple_bb (cur_stmt) != gimple_bb (src_stmt))
++	reset_flow_sensitive_info (gimple_assign_lhs (cur_stmt));
+       gsi_move_before (&gsi, &gsi_ins);
+       gsi = gsi_for_stmt (cur_stmt);
+ 
+--- a/gcc/tree-ssa-reassoc.c	2015-11-18 11:31:51.000000000 +0100
++++ b/gcc/tree-ssa-reassoc.c	2016-02-16 15:03:33.024469457 +0100
+@@ -3286,7 +3286,7 @@
+     any_changes = optimize_range_tests (ERROR_MARK, &ops);
+   if (any_changes)
+     {
+-      unsigned int idx;
++      unsigned int idx, max_idx = 0;
+       /* update_ops relies on has_single_use predicates returning the
+ 	 same values as it did during get_ops earlier.  Additionally it
+ 	 never removes statements, only adds new ones and it should walk
+@@ -3302,6 +3302,7 @@
+ 	    {
+ 	      tree new_op;
+ 
++	      max_idx = idx;
+ 	      stmt = last_stmt (bb);
+ 	      new_op = update_ops (bbinfo[idx].op,
+ 				   (enum tree_code)
+@@ -3371,6 +3372,10 @@
+ 	      && ops[bbinfo[idx].first_idx]->op != NULL_TREE)
+ 	    {
+ 	      gcond *cond_stmt = as_a <gcond *> (last_stmt (bb));
++
++	      if (idx > max_idx)
++		max_idx = idx;
++
+ 	      if (integer_zerop (ops[bbinfo[idx].first_idx]->op))
+ 		gimple_cond_make_false (cond_stmt);
+ 	      else if (integer_onep (ops[bbinfo[idx].first_idx]->op))
+@@ -3387,6 +3392,17 @@
+ 	  if (bb == first_bb)
+ 	    break;
+ 	}
++
++      /* The above changes could result in basic blocks after the first
++	 modified one, up to and including last_bb, to be executed even if
++	 they would not be in the original program.  If the value ranges of
++	 assignment lhs' in those bbs were dependent on the conditions
++	 guarding those basic blocks which now can change, the VRs might
++	 be incorrect.  As no_side_effect_bb should ensure those SSA_NAMEs
++	 are only used within the same bb, it should be not a big deal if
++	 we just reset all the VRs in those bbs.  See PR68671.  */
++      for (bb = last_bb, idx = 0; idx < max_idx; bb = single_pred (bb), idx++)
++	reset_flow_sensitive_info_in_bb (bb);
+     }
+ }
+ 
+--- a/gcc/tree-ssa-threadupdate.c	2015-03-25 23:49:47.000000000 +0100
++++ b/gcc/tree-ssa-threadupdate.c	2016-02-16 15:28:13.647992332 +0100
+@@ -254,6 +254,11 @@
+ 
+   /* Blocks duplicated for the thread.  */
+   bitmap duplicate_blocks;
++
++  /* When we have multiple paths through a joiner which reach different
++     final destinations, then we may need to correct for potential
++     profile insanities.  */
++  bool need_profile_correction;
+ };
+ 
+ /* Passes which use the jump threading code register jump threading
+@@ -827,7 +832,8 @@
+      So ensure that this path's path_out_count is at least the
+      difference between elast->count and nonpath_count.  Otherwise the edge
+      counts after threading will not be sane.  */
+-  if (has_joiner && path_out_count < elast->count - nonpath_count)
++  if (local_info->need_profile_correction
++      && has_joiner && path_out_count < elast->count - nonpath_count)
+   {
+     path_out_count = elast->count - nonpath_count;
+     /* But neither can we go above the minimum count along the path
+@@ -1496,6 +1502,7 @@
+   ssa_local_info_t local_info;
+ 
+   local_info.duplicate_blocks = BITMAP_ALLOC (NULL);
++  local_info.need_profile_correction = false;
+ 
+   /* To avoid scanning a linear array for the element we need we instead
+      use a hash table.  For normal code there should be no noticeable
+@@ -1506,6 +1513,7 @@
+ 
+   /* Record each unique threaded destination into a hash table for
+      efficient lookups.  */
++  edge last = NULL;
+   FOR_EACH_EDGE (e, ei, bb->preds)
+     {
+       if (e->aux == NULL)
+@@ -1559,6 +1567,17 @@
+       /* Insert the outgoing edge into the hash table if it is not
+ 	 already in the hash table.  */
+       lookup_redirection_data (e, INSERT);
++
++      /* When we have thread paths through a common joiner with different
++	 final destinations, then we may need corrections to deal with
++	 profile insanities.  See the big comment before compute_path_counts.  */
++      if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK)
++	{
++	  if (!last)
++	    last = e2;
++	  else if (e2 != last)
++	    local_info.need_profile_correction = true;
++	}
+     }
+ 
+   /* We do not update dominance info.  */
+--- a/gcc/tree-ssa-uninit.c	2015-09-09 19:14:29.000000000 +0200
++++ b/gcc/tree-ssa-uninit.c	2016-02-16 15:25:13.776504748 +0100
+@@ -1118,14 +1118,16 @@
+               edge opnd_edge;
+               unsigned uninit_opnds2
+                   = compute_uninit_opnds_pos (opnd_def_phi);
+-              gcc_assert (!MASK_EMPTY (uninit_opnds2));
+-              opnd_edge = gimple_phi_arg_edge (phi, i);
+-              if (!is_use_properly_guarded (phi,
+-                                            opnd_edge->src,
+-                                            opnd_def_phi,
+-                                            uninit_opnds2,
+-                                            visited_phis))
+-                  return false;
++              if (!MASK_EMPTY (uninit_opnds2))
++		{
++		  opnd_edge = gimple_phi_arg_edge (phi, i);
++		  if (!is_use_properly_guarded (phi,
++						opnd_edge->src,
++						opnd_def_phi,
++						uninit_opnds2,
++						visited_phis))
++		    return false;
++		}
+             }
+           else
+             return false;
+--- a/gcc/tree-vrp.c	2015-04-27 14:21:17.000000000 +0200
++++ b/gcc/tree-vrp.c	2016-02-16 15:42:05.696321686 +0100
+@@ -9534,7 +9534,8 @@
+       innerop = gimple_assign_rhs1 (def_stmt);
+ 
+       if (TREE_CODE (innerop) == SSA_NAME
+-	  && !POINTER_TYPE_P (TREE_TYPE (innerop)))
++	  && !POINTER_TYPE_P (TREE_TYPE (innerop))
++	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
+ 	{
+ 	  value_range_t *vr = get_value_range (innerop);
+ 
+@@ -9565,8 +9566,8 @@
+ 		  else
+ 		    location = gimple_location (stmt);
+ 		  warning_at (location, OPT_Wstrict_overflow,
+-		      "assuming signed overflow does not occur when "
+-		      "simplifying conditional");
++			      "assuming signed overflow does not occur when "
++			      "simplifying conditional");
+ 		}
+ 
+ 	      tree newconst = fold_convert (TREE_TYPE (innerop), op1);
+--- a/gcc/ubsan.c	2015-05-04 21:53:35.000000000 +0200
++++ b/gcc/ubsan.c	2016-02-16 15:42:02.435267264 +0100
+@@ -1611,6 +1611,7 @@
+     fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
+   else
+     {
++      initialize_sanitizer_builtins ();
+       /* Create the __ubsan_handle_float_cast_overflow fn call.  */
+       tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
+ 				     NULL, ubsan_type_descriptor (expr_type),
+--- a/gcc/varasm.c	2015-10-20 11:50:58.000000000 +0200
++++ b/gcc/varasm.c	2016-02-16 15:36:55.475350695 +0100
+@@ -1434,6 +1434,9 @@
+ 	 specifications.  */
+       SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
+       DECL_HARD_REGISTER (decl) = 0;
++      /* Also avoid SSA inconsistencies by pretending this is an external
++	 decl now.  */
++      DECL_EXTERNAL (decl) = 1;
+       return;
+     }
+   /* Now handle ordinary static variables and functions (in memory).
+--- a/gcc/var-tracking.c	2015-03-26 14:19:00.000000000 +0100
++++ b/gcc/var-tracking.c	2016-02-16 15:09:41.212623196 +0100
+@@ -5833,11 +5833,6 @@
+ 	    return;
+ 	}
+       ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
+-      if (ret == val)
+-	/* Ensure ret isn't VALUE itself (which can happen e.g. for
+-	   (plus (reg1) (reg2)) when reg2 is known to be 0), as that
+-	   breaks a lot of routines during var-tracking.  */
+-	ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx);
+       break;
+     default:
+       gcc_unreachable ();
+--- a/gcc/wide-int.cc	2015-10-17 05:55:03.000000000 +0200
++++ b/gcc/wide-int.cc	2016-02-16 15:42:14.394467025 +0100
+@@ -1808,15 +1808,32 @@
+     {
+       unsigned HOST_WIDE_INT o0 = dividend.to_uhwi ();
+       unsigned HOST_WIDE_INT o1 = divisor.to_uhwi ();
++      unsigned int quotient_len = 1;
+ 
+       if (quotient)
+-	quotient[0] = o0 / o1;
++	{
++	  quotient[0] = o0 / o1;
++	  if (o1 == 1
++	      && (HOST_WIDE_INT) o0 < 0
++	      && dividend_prec > HOST_BITS_PER_WIDE_INT)
++	    {
++	      quotient[1] = 0;
++	      quotient_len = 2;
++	    }
++	}
+       if (remainder)
+ 	{
+ 	  remainder[0] = o0 % o1;
+-	  *remainder_len = 1;
++	  if ((HOST_WIDE_INT) remainder[0] < 0
++	      && dividend_prec > HOST_BITS_PER_WIDE_INT)
++	    {
++	      remainder[1] = 0;
++	      *remainder_len = 2;
++	    }
++	  else
++	    *remainder_len = 1;
+ 	}
+-      return 1;
++      return quotient_len;
+     }
+ 
+   /* Make the divisor and dividend positive and remember what we
+--- a/gcc/wide-int.h	2015-10-19 21:44:58.000000000 +0200
++++ b/gcc/wide-int.h	2016-02-16 15:42:12.511435538 +0100
+@@ -2892,7 +2892,9 @@
+ 	 For variable-precision integers like wide_int, handle HWI
+ 	 and sub-HWI integers inline.  */
+       if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT)
+-	  ? xi.len == 1 && xi.val[0] >= 0
++	  ? (shift < HOST_BITS_PER_WIDE_INT
++	     && xi.len == 1
++	     && xi.val[0] >= 0)
+ 	  : xi.precision <= HOST_BITS_PER_WIDE_INT)
+ 	{
+ 	  val[0] = xi.to_uhwi () >> shift;
+--- a/libcpp/files.c	2015-11-19 09:28:43.000000000 +0100
++++ b/libcpp/files.c	2016-02-16 15:42:13.466451505 +0100
+@@ -522,7 +522,10 @@
+     return entry->u.file;
+ 
+   file = make_cpp_file (pfile, start_dir, fname);
+-  file->implicit_preinclude = implicit_preinclude;
++  file->implicit_preinclude
++    = (implicit_preinclude
++       || (pfile->buffer
++	   && pfile->buffer->file->implicit_preinclude));
+ 
+   /* Try each path in the include chain.  */
+   for (; !fake ;)
+--- a/libgcc/config/i386/morestack.S	2015-01-05 13:33:28.000000000 +0100
++++ b/libgcc/config/i386/morestack.S	2016-02-16 15:37:28.955863253 +0100
+@@ -732,6 +732,7 @@
+ 
+ 	leal	-16000(%esp),%eax	# We should have at least 16K.
+ 	movl	%eax,%gs:0x30
++	subl	$4,%esp			# Align stack.
+ 	pushl	$16000
+ 	pushl	%esp
+ #ifdef __PIC__
+@@ -739,13 +740,14 @@
+ #else
+ 	call	__generic_morestack_set_initial_sp
+ #endif
+-	addl	$8,%esp
++	addl	$12,%esp
+ 	ret
+ 
+ #else /* defined(__x86_64__) */
+ 
+ 	leaq	-16000(%rsp),%rax	# We should have at least 16K.
+ 	X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
++	subq	$8,%rsp			# Align stack.
+ 	movq	%rsp,%rdi
+ 	movq	$16000,%rsi
+ #ifdef __PIC__
+@@ -753,6 +755,7 @@
+ #else
+ 	call	__generic_morestack_set_initial_sp
+ #endif
++	addq	$8,%rsp
+ 	ret
+ 
+ #endif /* defined(__x86_64__) */
+--- a/libgfortran/caf/libcaf.h	2015-03-10 18:58:01.000000000 +0100
++++ b/libgfortran/caf/libcaf.h	2016-02-16 15:44:29.789760281 +0100
+@@ -57,7 +57,9 @@
+   CAF_REGTYPE_COARRAY_ALLOC,
+   CAF_REGTYPE_LOCK_STATIC,
+   CAF_REGTYPE_LOCK_ALLOC,
+-  CAF_REGTYPE_CRITICAL
++  CAF_REGTYPE_CRITICAL,
++  CAF_REGTYPE_EVENT_STATIC,
++  CAF_REGTYPE_EVENT_ALLOC
+ }
+ caf_register_t;
+ 
+@@ -133,5 +135,8 @@
+ 
+ void _gfortran_caf_lock (caf_token_t, size_t, int, int *, int *, char *, int);
+ void _gfortran_caf_unlock (caf_token_t, size_t, int, int *, char *, int);
++void _gfortran_caf_event_post (caf_token_t, size_t, int, int *, char *, int);
++void _gfortran_caf_event_wait (caf_token_t, size_t, int, int *, char *, int);
++void _gfortran_caf_event_query (caf_token_t, size_t, int, int *, int *);
+ 
+ #endif  /* LIBCAF_H  */
+--- a/libgfortran/caf/single.c	2015-03-11 22:42:56.000000000 +0100
++++ b/libgfortran/caf/single.c	2016-02-16 15:44:29.789760281 +0100
+@@ -101,7 +101,8 @@
+   void *local;
+ 
+   if (type == CAF_REGTYPE_LOCK_STATIC || type == CAF_REGTYPE_LOCK_ALLOC
+-      || type == CAF_REGTYPE_CRITICAL)
++      || type == CAF_REGTYPE_CRITICAL || type == CAF_REGTYPE_EVENT_STATIC
++      || type == CAF_REGTYPE_EVENT_ALLOC)
+     local = calloc (size, sizeof (bool));
+   else
+     local = malloc (size);
+@@ -133,7 +134,8 @@
+     *stat = 0;
+ 
+   if (type == CAF_REGTYPE_COARRAY_STATIC || type == CAF_REGTYPE_LOCK_STATIC
+-      || type == CAF_REGTYPE_CRITICAL)
++      || type == CAF_REGTYPE_CRITICAL || type == CAF_REGTYPE_EVENT_STATIC
++      || type == CAF_REGTYPE_EVENT_ALLOC)
+     {
+       caf_static_t *tmp = malloc (sizeof (caf_static_t));
+       tmp->prev  = caf_static_list;
+@@ -1071,6 +1073,45 @@
+     *stat = 0;
+ }
+ 
++void
++_gfortran_caf_event_post (caf_token_t token, size_t index, 
++			  int image_index __attribute__ ((unused)), 
++			  int *stat, char *errmsg __attribute__ ((unused)), 
++			  int errmsg_len __attribute__ ((unused)))
++{
++  uint32_t value = 1;
++  uint32_t *event = (uint32_t *) ((char *) TOKEN (token) + index*sizeof(uint32_t));
++  __atomic_fetch_add (event, (uint32_t) value, __ATOMIC_RELAXED);
++  
++  if(stat)
++    *stat = 0;
++}
++
++void
++_gfortran_caf_event_wait (caf_token_t token, size_t index, 
++			  int until_count, int *stat,
++			  char *errmsg __attribute__ ((unused)), 
++			  int errmsg_len __attribute__ ((unused)))
++{
++  uint32_t *event = (uint32_t *) ((char *) TOKEN (token) + index*sizeof(uint32_t));
++  uint32_t value = (uint32_t)-until_count;
++   __atomic_fetch_add (event, (uint32_t) value, __ATOMIC_RELAXED);
++  
++   if(stat)
++    *stat = 0;    
++}
++
++void
++_gfortran_caf_event_query (caf_token_t token, size_t index, 
++			   int image_index __attribute__ ((unused)), 
++			   int *count, int *stat)
++{
++  uint32_t *event = (uint32_t *) ((char *) TOKEN (token) + index*sizeof(uint32_t));
++  __atomic_load (event, (uint32_t *) count, __ATOMIC_RELAXED);
++  
++  if(stat)
++    *stat = 0;
++}
+ 
+ void
+ _gfortran_caf_lock (caf_token_t token, size_t index,
+--- a/libgfortran/io/format.c	2015-11-07 19:13:17.000000000 +0100
++++ b/libgfortran/io/format.c	2016-02-16 15:18:46.431886288 +0100
+@@ -1171,26 +1171,6 @@
+   *p++ = '^';
+   *p = '\0';
+ 
+-  /* Cleanup any left over memory allocations before calling generate
+-     error.  */
+-  if (is_internal_unit (dtp))
+-    {
+-      if (dtp->format != NULL)
+-	{
+-	  free (dtp->format);
+-	  dtp->format = NULL;
+-	}
+-
+-      /* Leave these alone if IOSTAT was given because execution will
+-	 return from generate error in those cases.  */
+-      if (!(dtp->common.flags & IOPARM_HAS_IOSTAT))
+-	{
+-	  free (dtp->u.p.fmt);
+-	  free_format_hash_table (dtp->u.p.current_unit);
+-	  free_internal_unit (dtp);
+-	}
+-    }
+-
+   generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
+ }
+ 
+--- a/libgfortran/io/list_read.c	2015-02-07 16:13:15.000000000 +0100
++++ b/libgfortran/io/list_read.c	2016-02-16 15:45:10.693463219 +0100
+@@ -58,7 +58,8 @@
+ /* This macro assumes that we're operating on a variable.  */
+ 
+ #define is_separator(c) (c == '/' ||  c == ',' || c == '\n' || c == ' ' \
+-                         || c == '\t' || c == '\r' || c == ';')
++                         || c == '\t' || c == '\r' || c == ';' || \
++			 (dtp->u.p.namelist_mode && c == '!'))
+ 
+ /* Maximum repeat count.  Less than ten times the maximum signed int32.  */
+ 
+@@ -75,7 +76,7 @@
+ 
+ /* Worker function to save a default KIND=1 character to a string
+    buffer, enlarging it as necessary.  */
+-   
++
+ static void
+ push_char_default (st_parameter_dt *dtp, int c)
+ {
+@@ -92,13 +93,8 @@
+   if (dtp->u.p.saved_used >= dtp->u.p.saved_length)
+     {
+       dtp->u.p.saved_length = 2 * dtp->u.p.saved_length;
+-      dtp->u.p.saved_string = 
++      dtp->u.p.saved_string =
+ 	xrealloc (dtp->u.p.saved_string, dtp->u.p.saved_length);
+-      
+-      // Also this should not be necessary.
+-      memset (dtp->u.p.saved_string + dtp->u.p.saved_used, 0, 
+-	      dtp->u.p.saved_length - dtp->u.p.saved_used);
+-
+     }
+ 
+   dtp->u.p.saved_string[dtp->u.p.saved_used++] = (char) c;
+@@ -107,11 +103,10 @@
+ 
+ /* Worker function to save a KIND=4 character to a string buffer,
+    enlarging the buffer as necessary.  */
+-   
+ static void
+ push_char4 (st_parameter_dt *dtp, int c)
+ {
+-  gfc_char4_t *new, *p = (gfc_char4_t *) dtp->u.p.saved_string;
++  gfc_char4_t *p = (gfc_char4_t *) dtp->u.p.saved_string;
+ 
+   if (p == NULL)
+     {
+@@ -125,9 +120,6 @@
+     {
+       dtp->u.p.saved_length = 2 * dtp->u.p.saved_length;
+       p = xrealloc (p, dtp->u.p.saved_length * sizeof (gfc_char4_t));
+-      
+-      memset4 (new + dtp->u.p.saved_used, 0, 
+-	      dtp->u.p.saved_length - dtp->u.p.saved_used);
+     }
+ 
+   p[dtp->u.p.saved_used++] = c;
+@@ -168,7 +160,7 @@
+ /* Unget saves the last character so when reading the next character,
+    we need to check to see if there is a character waiting.  Similar,
+    if the line buffer is being used to read_logical, check it too.  */
+-   
++
+ static int
+ check_buffers (st_parameter_dt *dtp)
+ {
+@@ -200,7 +192,7 @@
+       dtp->u.p.line_buffer_pos = 0;
+       dtp->u.p.line_buffer_enabled = 0;
+     }
+-    
++
+ done:
+   dtp->u.p.at_eol = (c == '\n' || c == EOF);
+   return c;
+@@ -254,7 +246,7 @@
+ 	  record = next_array_record (dtp, dtp->u.p.current_unit->ls,
+ 				      &finished);
+ 
+-	  /* Check for "end-of-file" condition.  */      
++	  /* Check for "end-of-file" condition.  */
+ 	  if (finished)
+ 	    {
+ 	      dtp->u.p.at_eof = 1;
+@@ -289,17 +281,17 @@
+ 
+   if (is_array_io (dtp))
+     {
+-      /* Check whether we hit EOF.  */ 
++      /* Check whether we hit EOF.  */
+       if (unlikely (length == 0))
+ 	{
+ 	  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
+ 	  return '\0';
+-	} 
++	}
+       dtp->u.p.current_unit->bytes_left--;
+     }
+   else
+     {
+-      if (dtp->u.p.at_eof) 
++      if (dtp->u.p.at_eof)
+ 	return EOF;
+       if (length == 0)
+ 	{
+@@ -316,7 +308,7 @@
+ 
+ /* Worker function for UTF encoded files.  */
+ static int
+-next_char_utf8 (st_parameter_dt *dtp) 
++next_char_utf8 (st_parameter_dt *dtp)
+ {
+   static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 };
+   static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+@@ -336,7 +328,7 @@
+     if ((c & ~masks[nb-1]) == patns[nb-1])
+       goto found;
+   goto invalid;
+-	
++
+  found:
+   c = (c & masks[nb-1]);
+ 
+@@ -363,7 +355,7 @@
+ utf_done:
+   dtp->u.p.at_eol = (c == '\n' || c == (gfc_char4_t) EOF);
+   return (int) c;
+-      
++
+  invalid:
+   generate_error (&dtp->common, LIBERROR_READ_VALUE, "Invalid UTF-8 encoding");
+   return (gfc_char4_t) '?';
+@@ -457,7 +449,7 @@
+    separator, we stop reading.  If there are more input items, we
+    continue reading the separator with finish_separator() which takes
+    care of the fact that we may or may not have seen a comma as part
+-   of the separator. 
++   of the separator.
+ 
+    Returns 0 for success, and non-zero error code otherwise.  */
+ 
+@@ -521,12 +513,12 @@
+       break;
+ 
+     case '!':
++      /* Eat a namelist comment.  */
+       if (dtp->u.p.namelist_mode)
+-	{			/* Eat a namelist comment.  */
++	{
+ 	  err = eat_line (dtp);
+ 	  if (err)
+ 	    return err;
+-
+ 	  break;
+ 	}
+ 
+@@ -786,7 +778,7 @@
+ 
+ 
+ /* To read a logical we have to look ahead in the input stream to make sure
+-    there is not an equal sign indicating a variable name.  To do this we use 
++    there is not an equal sign indicating a variable name.  To do this we use
+     line_buffer to point to a temporary buffer, pushing characters there for
+     possible later reading. */
+ 
+@@ -852,6 +844,10 @@
+ 
+       break;
+ 
++    case '!':
++      if (!dtp->u.p.namelist_mode)
++        goto bad_logical;
++
+     CASE_SEPARATORS:
+     case EOF:
+       unget_char (dtp, c);
+@@ -900,7 +896,7 @@
+ 	      goto logical_done;
+ 	    }
+ 	}
+- 
++
+       l_push_char (dtp, c);
+       if (c == '=')
+ 	{
+@@ -909,7 +905,7 @@
+ 	  dtp->u.p.line_buffer_pos = 0;
+ 	  return;
+ 	}
+-      
++
+     }
+ 
+  bad_logical:
+@@ -971,6 +967,10 @@
+ 	goto bad_integer;
+       goto get_integer;
+ 
++    case '!':
++      if (!dtp->u.p.namelist_mode)
++        goto bad_integer;
++
+     CASE_SEPARATORS:		/* Single null.  */
+       unget_char (dtp, c);
+       eat_separator (dtp);
+@@ -999,6 +999,10 @@
+ 	  push_char (dtp, '\0');
+ 	  goto repeat;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad_integer;
++
+ 	CASE_SEPARATORS:	/* Not a repeat count.  */
+ 	case EOF:
+ 	  goto done;
+@@ -1021,6 +1025,10 @@
+     CASE_DIGITS:
+       break;
+ 
++    case '!':
++      if (!dtp->u.p.namelist_mode)
++        goto bad_integer;
++
+     CASE_SEPARATORS:
+       unget_char (dtp, c);
+       eat_separator (dtp);
+@@ -1049,6 +1057,10 @@
+ 	  push_char (dtp, c);
+ 	  break;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad_integer;
++
+ 	CASE_SEPARATORS:
+ 	case EOF:
+ 	  goto done;
+@@ -1063,7 +1075,7 @@
+   if (nml_bad_return (dtp, c))
+     return;
+ 
+-  free_saved (dtp);  
++  free_saved (dtp);
+   if (c == EOF)
+     {
+       free_line (dtp);
+@@ -1128,21 +1140,6 @@
+     default:
+       if (dtp->u.p.namelist_mode)
+ 	{
+-	  if (dtp->u.p.current_unit->delim_status == DELIM_NONE)
+-	    {
+-	      /* No delimiters so finish reading the string now.  */
+-	      int i;
+-	      push_char (dtp, c);
+-	      for (i = dtp->u.p.ionml->string_length; i > 1; i--)
+-		{
+-		  if ((c = next_char (dtp)) == EOF)
+-		    goto done_eof;
+-		  push_char (dtp, c);
+-		}
+-	      dtp->u.p.saved_type = BT_CHARACTER;
+-	      free_line (dtp);
+-	      return;
+-	    }
+ 	  unget_char (dtp, c);
+ 	  return;
+ 	}
+@@ -1216,10 +1213,10 @@
+ 	      push_char (dtp, c);
+ 	      break;
+ 	    }
+-  
++
+ 	  /* See if we have a doubled quote character or the end of
+ 	     the string.  */
+-  
++
+ 	  if ((c = next_char (dtp)) == EOF)
+ 	    goto done_eof;
+ 	  if (c == quote)
+@@ -1227,21 +1224,21 @@
+ 	      push_char (dtp, quote);
+ 	      break;
+ 	    }
+-  
++
+ 	  unget_char (dtp, c);
+ 	  goto done;
+-  
++
+ 	CASE_SEPARATORS:
+ 	  if (quote == ' ')
+ 	    {
+ 	      unget_char (dtp, c);
+ 	      goto done;
+ 	    }
+-  
++
+ 	  if (c != '\n' && c != '\r')
+ 	    push_char (dtp, c);
+ 	  break;
+-  
++
+ 	default:
+ 	  push_char (dtp, c);
+ 	  break;
+@@ -1253,13 +1250,13 @@
+  done:
+   c = next_char (dtp);
+  done_eof:
+-  if (is_separator (c) || c == '!' || c == EOF)
++  if (is_separator (c) || c == EOF)
+     {
+       unget_char (dtp, c);
+       eat_separator (dtp);
+       dtp->u.p.saved_type = BT_CHARACTER;
+     }
+-  else 
++  else
+     {
+       free_saved (dtp);
+       snprintf (message, MSGLEN, "Invalid string input in item %d",
+@@ -1287,7 +1284,7 @@
+ 
+   if ((c = next_char (dtp)) == EOF)
+     goto bad;
+-    
++
+   if (c == '-' || c == '+')
+     {
+       push_char (dtp, c);
+@@ -1297,7 +1294,7 @@
+ 
+   if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
+     c = '.';
+-  
++
+   if (!isdigit (c) && c != '.')
+     {
+       if (c == 'i' || c == 'I' || c == 'n' || c == 'N')
+@@ -1347,6 +1344,10 @@
+ 	    goto bad;
+ 	  goto exp2;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad;
++
+ 	CASE_SEPARATORS:
+ 	case EOF:
+ 	  goto done;
+@@ -1383,6 +1384,10 @@
+ 	  push_char (dtp, c);
+ 	  break;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad;
++
+ 	CASE_SEPARATORS:
+ 	case EOF:
+ 	  unget_char (dtp, c);
+@@ -1443,7 +1448,7 @@
+       push_char (dtp, 'n');
+       push_char (dtp, 'a');
+       push_char (dtp, 'n');
+-      
++
+       /* Match "NAN(alphanum)".  */
+       if (c == '(')
+ 	{
+@@ -1500,6 +1505,10 @@
+     case '(':
+       break;
+ 
++    case '!':
++      if (!dtp->u.p.namelist_mode)
++	goto bad_complex;
++
+     CASE_SEPARATORS:
+     case EOF:
+       unget_char (dtp, c);
+@@ -1543,7 +1552,7 @@
+ 
+   if (parse_real (dtp, dest + size / 2, kind))
+     return;
+-    
++
+ eol_4:
+   eat_spaces (dtp);
+   c = next_char (dtp);
+@@ -1578,7 +1587,7 @@
+       hit_eof (dtp);
+       return;
+     }
+-  else if (c != '\n')   
++  else if (c != '\n')
+     eat_line (dtp);
+ 
+   snprintf (message, MSGLEN, "Bad complex value in item %d of list input",
+@@ -1618,6 +1627,10 @@
+     case '-':
+       goto got_sign;
+ 
++    case '!':
++      if (!dtp->u.p.namelist_mode)
++	goto bad_real;
++
+     CASE_SEPARATORS:
+       unget_char (dtp, c);		/* Single null.  */
+       eat_separator (dtp);
+@@ -1673,6 +1686,10 @@
+ 	  push_char (dtp, '\0');
+ 	  goto got_repeat;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad_real;
++
+ 	CASE_SEPARATORS:
+ 	case EOF:
+           if (c != '\n' && c != ',' && c != '\r' && c != ';')
+@@ -1742,6 +1759,10 @@
+ 	  push_char (dtp, c);
+ 	  break;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad_real;
++
+ 	CASE_SEPARATORS:
+ 	case EOF:
+ 	  goto done;
+@@ -1802,6 +1823,10 @@
+ 	  push_char (dtp, c);
+ 	  break;
+ 
++	case '!':
++	  if (!dtp->u.p.namelist_mode)
++	    goto bad_real;
++
+ 	CASE_SEPARATORS:
+ 	case EOF:
+ 	  goto done;
+@@ -1899,7 +1924,7 @@
+     goto unwind;
+ 
+   if (dtp->u.p.namelist_mode)
+-    {	
++    {
+       if (c == ' ' || c =='\n' || c == '\r')
+ 	{
+ 	  do
+@@ -2058,7 +2083,7 @@
+       dtp->u.p.input_complete = 0;
+       dtp->u.p.repeat_count = 1;
+       dtp->u.p.at_eol = 0;
+-      
++
+       if ((c = eat_spaces (dtp)) == EOF)
+ 	{
+ 	  err = LIBERROR_END;
+@@ -2092,7 +2117,7 @@
+ 	    return err;
+ 	  goto set_value;
+ 	}
+-	
++
+       if (dtp->u.p.input_complete)
+ 	goto cleanup;
+ 
+@@ -2231,7 +2256,7 @@
+   for (elem = 0; elem < nelems; elem++)
+     {
+       dtp->u.p.item_count++;
+-      err = list_formatted_read_scalar (dtp, type, tmp + stride*elem, 
++      err = list_formatted_read_scalar (dtp, type, tmp + stride*elem,
+ 					kind, size);
+       if (err)
+ 	break;
+@@ -2374,10 +2399,10 @@
+ 		      || (c==')' && dim < rank -1))
+ 		    {
+ 		      if (is_char)
+-		        snprintf (parse_err_msg, parse_err_msg_size, 
++		        snprintf (parse_err_msg, parse_err_msg_size,
+ 				  "Bad substring qualifier");
+ 		      else
+-			snprintf (parse_err_msg, parse_err_msg_size, 
++			snprintf (parse_err_msg, parse_err_msg_size,
+ 				 "Bad number of index fields");
+ 		      goto err_ret;
+ 		    }
+@@ -2396,7 +2421,7 @@
+ 		    snprintf (parse_err_msg, parse_err_msg_size,
+ 			     "Bad character in substring qualifier");
+ 		  else
+-		    snprintf (parse_err_msg, parse_err_msg_size, 
++		    snprintf (parse_err_msg, parse_err_msg_size,
+ 			      "Bad character in index");
+ 		  goto err_ret;
+ 		}
+@@ -2405,10 +2430,10 @@
+ 		  && dtp->u.p.saved_string == 0)
+ 		{
+ 		  if (is_char)
+-		    snprintf (parse_err_msg, parse_err_msg_size, 
++		    snprintf (parse_err_msg, parse_err_msg_size,
+ 			      "Null substring qualifier");
+ 		  else
+-		    snprintf (parse_err_msg, parse_err_msg_size, 
++		    snprintf (parse_err_msg, parse_err_msg_size,
+ 			      "Null index field");
+ 		  goto err_ret;
+ 		}
+@@ -2417,7 +2442,7 @@
+ 		  || (indx == 2 && dtp->u.p.saved_string == 0))
+ 		{
+ 		  if (is_char)
+-		    snprintf (parse_err_msg, parse_err_msg_size, 
++		    snprintf (parse_err_msg, parse_err_msg_size,
+ 			      "Bad substring qualifier");
+ 		  else
+ 		    snprintf (parse_err_msg, parse_err_msg_size,
+@@ -2506,10 +2531,10 @@
+ 	   || (ls[dim].end < GFC_DIMENSION_LBOUND(ad[dim])))
+ 	{
+ 	  if (is_char)
+-	    snprintf (parse_err_msg, parse_err_msg_size, 
++	    snprintf (parse_err_msg, parse_err_msg_size,
+ 		      "Substring out of range");
+ 	  else
+-	    snprintf (parse_err_msg, parse_err_msg_size, 
++	    snprintf (parse_err_msg, parse_err_msg_size,
+ 		      "Index %d out of range", dim + 1);
+ 	  goto err_ret;
+ 	}
+@@ -2517,7 +2542,7 @@
+       if (((ls[dim].end - ls[dim].start ) * ls[dim].step < 0)
+ 	  || (ls[dim].step == 0))
+ 	{
+-	  snprintf (parse_err_msg, parse_err_msg_size, 
++	  snprintf (parse_err_msg, parse_err_msg_size,
+ 		   "Bad range in index %d", dim + 1);
+ 	  goto err_ret;
+ 	}
+@@ -2560,7 +2585,7 @@
+ strcmp_extended_type (char *p, char *q)
+ {
+   char *r, *s;
+-  
++
+   for (r = p, s = q; *r && *s; r++, s++)
+     {
+       if (*r != *s)
+@@ -3068,7 +3093,7 @@
+ 	goto nml_err_ret;
+       if (c != '?')
+ 	{
+-	  snprintf (nml_err_msg, nml_err_msg_size, 
++	  snprintf (nml_err_msg, nml_err_msg_size,
+ 		    "namelist read: misplaced = sign");
+ 	  goto nml_err_ret;
+ 	}
+@@ -3084,7 +3109,7 @@
+       nml_match_name (dtp, "end", 3);
+       if (dtp->u.p.nml_read_error)
+ 	{
+-	  snprintf (nml_err_msg, nml_err_msg_size, 
++	  snprintf (nml_err_msg, nml_err_msg_size,
+ 		    "namelist not terminated with / or &end");
+ 	  goto nml_err_ret;
+ 	}
+@@ -3379,7 +3404,7 @@
+   dtp->u.p.namelist_mode = 1;
+   dtp->u.p.input_complete = 0;
+   dtp->u.p.expanded_read = 0;
+-  
++
+   /* Set the next_char and push_char worker functions.  */
+   set_workers (dtp);
+ 
+@@ -3425,7 +3450,7 @@
+   if (dtp->u.p.nml_read_error)
+     goto find_nml_name;
+ 
+-  /* A trailing space is required, we give a little latitude here, 10.9.1.  */ 
++  /* A trailing space is required, we give a little latitude here, 10.9.1.  */
+   c = next_char (dtp);
+   if (!is_separator(c) && c != '!')
+     {
+--- a/libgfortran/io/write_float.def	2015-02-11 05:29:06.000000000 +0100
++++ b/libgfortran/io/write_float.def	2016-02-16 15:03:07.897992463 +0100
+@@ -938,7 +938,7 @@
+ 
+ #if defined(GFC_REAL_16_IS_FLOAT128)
+ #define DTOA2Q(prec,val)							\
+-__qmath_(quadmath_snprintf) (buffer, size, "%+-#.*Qe", (prec), (val))
++quadmath_snprintf (buffer, size, "%+-#.*Qe", (prec), (val))
+ #endif
+ 
+ #define FDTOA(suff,prec,val) TOKENPASTE(FDTOA2,suff)(prec,val)
+@@ -953,7 +953,7 @@
+ 
+ #if defined(GFC_REAL_16_IS_FLOAT128)
+ #define FDTOA2Q(prec,val)			       \
+-__qmath_(quadmath_snprintf) (buffer, size, "%+-#.*Qf", \
++quadmath_snprintf (buffer, size, "%+-#.*Qf", \
+ 			     (prec), (val))
+ #endif
+ 
+--- a/libgo/mksysinfo.sh	2015-11-11 15:16:46.000000000 +0100
++++ b/libgo/mksysinfo.sh	2016-02-16 15:31:11.849428548 +0100
+@@ -183,6 +183,12 @@
+ #ifdef TIOCSCTTY
+   TIOCSCTTY_val = TIOCSCTTY,
+ #endif
++#ifdef TIOCGPGRP
++  TIOCGPGRP_val = TIOCGPGRP,
++#endif
++#ifdef TIOCSPGRP
++  TIOCSPGRP_val = TIOCSPGRP,
++#endif
+ #ifdef TIOCGPTN
+   TIOCGPTN_val = TIOCGPTN,
+ #endif
+@@ -261,6 +267,9 @@
+ #ifdef TUNGETFILTER
+   TUNGETFILTER_val = TUNGETFILTER,
+ #endif
++#ifdef NLA_HDRLEN
++  NLA_HDRLEN_val = NLA_HDRLEN,
++#endif
+ 
+ };
+ EOF
+@@ -531,7 +540,7 @@
+ # GNU/Linux specific; it should do no harm if there is no
+ # _user_regs_struct.
+ regs=`grep '^type _user_regs_struct struct' gen-sysinfo.go || true`
+-if test "$regs" == ""; then
++if test "$regs" = ""; then
+   # s390
+   regs=`grep '^type __user_regs_struct struct' gen-sysinfo.go || true`
+   if test "$regs" != ""; then
+@@ -875,11 +884,13 @@
+       -e 's/ ai_/ Ai_/g' \
+     >> ${OUT}
+ 
+-# The addrinfo flags and errors.
++# The addrinfo and nameinfo flags and errors.
+ grep '^const _AI_' gen-sysinfo.go | \
+   sed -e 's/^\(const \)_\(AI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+ grep '^const _EAI_' gen-sysinfo.go | \
+   sed -e 's/^\(const \)_\(EAI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
++grep '^const _NI_' gen-sysinfo.go | \
++  sed -e 's/^\(const \)_\(NI_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+ 
+ # The passwd struct.
+ grep '^type _passwd ' gen-sysinfo.go | \
+@@ -915,6 +926,16 @@
+     echo 'const TIOCSCTTY = _TIOCSCTTY_val' >> ${OUT}
+   fi
+ fi
++if ! grep '^const TIOCGPGRP' ${OUT} >/dev/null 2>&1; then
++  if grep '^const _TIOCGPGRP_val' ${OUT} >/dev/null 2>&1; then
++    echo 'const TIOCGPGRP = _TIOCGPGRP_val' >> ${OUT}
++  fi
++fi
++if ! grep '^const TIOCSPGRP' ${OUT} >/dev/null 2>&1; then
++  if grep '^const _TIOCSPGRP_val' ${OUT} >/dev/null 2>&1; then
++    echo 'const TIOCSPGRP = _TIOCSPGRP_val' >> ${OUT}
++  fi
++fi
+ if ! grep '^const TIOCGPTN' ${OUT} >/dev/null 2>&1; then
+   if grep '^const _TIOCGPTN_val' ${OUT} >/dev/null 2>&1; then
+     echo 'const TIOCGPTN = _TIOCGPTN_val' >> ${OUT}
+@@ -1057,8 +1078,6 @@
+   fi
+ fi
+ 
+-
+-
+ # The ioctl flags for terminal control
+ grep '^const _TC[GS]ET' gen-sysinfo.go | grep -v _val | \
+     sed -e 's/^\(const \)_\(TC[GS]ET[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+@@ -1404,9 +1423,15 @@
+ # The GNU/Linux netlink flags.
+ grep '^const _NETLINK_' gen-sysinfo.go | \
+   sed -e 's/^\(const \)_\(NETLINK_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+-grep '^const _NLA_' gen-sysinfo.go | \
++grep '^const _NLA_' gen-sysinfo.go | grep -v '_val =' | \
+   sed -e 's/^\(const \)_\(NLA_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+ 
++if ! grep '^const NLA_HDRLEN' ${OUT} >/dev/null 2>&1; then
++  if grep '^const _NLA_HDRLEN_val' ${OUT} >/dev/null 2>&1; then
++    echo 'const NLA_HDRLEN = _NLA_HDRLEN_val' >> ${OUT}
++  fi
++fi
++
+ # The GNU/Linux packet socket flags.
+ grep '^const _PACKET_' gen-sysinfo.go | \
+   sed -e 's/^\(const \)_\(PACKET_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+@@ -1426,6 +1451,11 @@
+ # The GNU/Linux CLONE flags.
+ grep '^const _CLONE_' gen-sysinfo.go | \
+   sed -e 's/^\(const \)_\(CLONE_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
++# We need some CLONE constants that are not defined in older versions
++# of glibc.
++if ! grep '^const CLONE_NEWUSER ' ${OUT} > /dev/null 2>&1; then
++  echo "const CLONE_NEWUSER = 0x10000000" >> ${OUT}
++fi
+ 
+ # Struct sizes.
+ set cmsghdr Cmsghdr ip_mreq IPMreq ip_mreqn IPMreqn ipv6_mreq IPv6Mreq \
+--- a/libmpx/mpxrt/mpxrt.c	2015-03-10 10:37:41.000000000 +0100
++++ b/libmpx/mpxrt/mpxrt.c	2016-02-16 15:29:46.587786427 +0100
+@@ -296,7 +296,7 @@
+       __mpxrt_write_uint (VERB_ERROR, trapno, 10);
+       __mpxrt_write (VERB_ERROR, ", ip = 0x");
+       __mpxrt_write_uint (VERB_ERROR, ip, 16);
+-      __mpxrt_write (VERB_BR, "\n");
++      __mpxrt_write (VERB_ERROR, "\n");
+       exit (255);
+     }
+   else
+@@ -305,7 +305,7 @@
+       __mpxrt_write_uint (VERB_ERROR, trapno, 10);
+       __mpxrt_write (VERB_ERROR, "! at 0x");
+       __mpxrt_write_uint (VERB_ERROR, ip, 16);
+-      __mpxrt_write (VERB_BR, "\n");
++      __mpxrt_write (VERB_ERROR, "\n");
+       exit (255);
+     }
+ }
+--- a/libsanitizer/asan/asan_mac.cc	2014-11-13 21:41:38.000000000 +0100
++++ b/libsanitizer/asan/asan_mac.cc	2016-02-16 15:24:56.841175125 +0100
+@@ -99,6 +99,23 @@
+   }
+ }
+ 
++bool DyldNeedsEnvVariable() {
++// If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
++// DYLD_INSERT_LIBRARIES is not set.
++
++#if SANITIZER_IOSSIM
++  // GetMacosVersion will not work for the simulator, whose kernel version
++  // is tied to the host. Use a weak linking hack for the simulator.
++  // This API was introduced in the same version of the OS as the dyld
++  // optimization.
++
++  // Check for presence of a symbol that is available on OS X 10.11+, iOS 9.0+.
++  return (dlsym(RTLD_NEXT, "mach_memory_info") == nullptr);
++#else
++  return (GetMacosVersion() <= MACOS_VERSION_YOSEMITE);
++#endif
++}
++
+ void MaybeReexec() {
+   if (!flags()->allow_reexec) return;
+   // Make sure the dynamic ASan runtime library is preloaded so that the
+@@ -111,8 +128,9 @@
+   uptr old_env_len = dyld_insert_libraries ?
+       internal_strlen(dyld_insert_libraries) : 0;
+   uptr fname_len = internal_strlen(info.dli_fname);
+-  if (!dyld_insert_libraries ||
+-      !REAL(strstr)(dyld_insert_libraries, info.dli_fname)) {
++  bool lib_is_in_env =
++      dyld_insert_libraries && REAL(strstr)(dyld_insert_libraries, info.dli_fname);
++  if (DyldNeedsEnvVariable() && !lib_is_in_env) {
+     // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
+     // library.
+     char program_name[1024];
+@@ -141,6 +159,10 @@
+     VReport(1, "Set ASAN_OPTIONS=allow_reexec=0 to disable this.\n");
+     execv(program_name, *_NSGetArgv());
+   } else {
++
++    if (!lib_is_in_env)
++      return;
++
+     // DYLD_INSERT_LIBRARIES is set and contains the runtime library.
+     if (old_env_len == fname_len) {
+       // It's just the runtime library name - fine to unset the variable.
+--- a/libsanitizer/sanitizer_common/sanitizer_mac.cc	2014-11-13 21:41:38.000000000 +0100
++++ b/libsanitizer/sanitizer_common/sanitizer_mac.cc	2016-02-16 15:24:56.841175125 +0100
+@@ -296,7 +296,11 @@
+         case '2': return MACOS_VERSION_MOUNTAIN_LION;
+         case '3': return MACOS_VERSION_MAVERICKS;
+         case '4': return MACOS_VERSION_YOSEMITE;
+-        default: return MACOS_VERSION_UNKNOWN;
++        default:
++          if (IsDigit(version[1]))
++            return MACOS_VERSION_UNKNOWN_NEWER;
++          else
++            return MACOS_VERSION_UNKNOWN;
+       }
+     }
+     default: return MACOS_VERSION_UNKNOWN;
+--- a/libsanitizer/sanitizer_common/sanitizer_mac.h	2014-11-13 21:41:38.000000000 +0100
++++ b/libsanitizer/sanitizer_common/sanitizer_mac.h	2016-02-16 15:24:56.841175125 +0100
+@@ -25,6 +25,7 @@
+   MACOS_VERSION_MOUNTAIN_LION,
+   MACOS_VERSION_MAVERICKS,
+   MACOS_VERSION_YOSEMITE,
++  MACOS_VERSION_UNKNOWN_NEWER
+ };
+ 
+ MacosVersion GetMacosVersion();
+--- a/libstdc++-v3/include/backward/strstream	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/backward/strstream	2016-02-16 15:09:05.791852030 +0100
+@@ -40,9 +40,8 @@
+ // MAY BE REMOVED in a future standard revision.  One should use the
+ // header <sstream> instead.
+ 
+-/** @file backward/strstream
+- *  This is an internal header file, included by other library headers.
+- *  Do not attempt to use it directly. @headername{sstream}
++/** @file strstream
++ *  This is a Standard C++ Library header.
+  */
+ 
+ #ifndef _BACKWARD_STRSTREAM
+--- a/libstdc++-v3/include/bits/alloc_traits.h	2015-05-28 14:33:26.000000000 +0200
++++ b/libstdc++-v3/include/bits/alloc_traits.h	2016-02-16 15:44:11.879453856 +0100
+@@ -409,7 +409,7 @@
+        *  Calls @c __a.destroy(__p) if that expression is well-formed,
+        *  otherwise calls @c __p->~_Tp()
+       */
+-      template <class _Tp>
++      template<typename _Tp>
+ 	static void destroy(_Alloc& __a, _Tp* __p)
+ 	{ _S_destroy(__a, __p); }
+ 
+@@ -437,6 +437,130 @@
+       { return _S_select(__rhs, 0); }
+     };
+ 
++  /// Partial specialization for std::allocator.
++  template<typename _Tp>
++    struct allocator_traits<allocator<_Tp>>
++    {
++      /// The allocator type
++      using allocator_type = allocator<_Tp>;
++      /// The allocated type
++      using value_type = _Tp;
++
++      /// The allocator's pointer type.
++      using pointer = _Tp*;
++
++      /// The allocator's const pointer type.
++      using const_pointer = const _Tp*;
++
++      /// The allocator's void pointer type.
++      using void_pointer = void*;
++
++      /// The allocator's const void pointer type.
++      using const_void_pointer = const void*;
++
++      /// The allocator's difference type
++      using difference_type = std::ptrdiff_t;
++
++      /// The allocator's size type
++      using size_type = std::size_t;
++
++      /// How the allocator is propagated on copy assignment
++      using propagate_on_container_copy_assignment = false_type;
++
++      /// How the allocator is propagated on move assignment
++      using propagate_on_container_move_assignment = true_type;
++
++      /// How the allocator is propagated on swap
++      using propagate_on_container_swap = false_type;
++
++      template<typename _Up>
++	using rebind_alloc = allocator<_Up>;
++
++      template<typename _Up>
++	using rebind_traits = allocator_traits<allocator<_Up>>;
++
++      /**
++       *  @brief  Allocate memory.
++       *  @param  __a  An allocator.
++       *  @param  __n  The number of objects to allocate space for.
++       *
++       *  Calls @c a.allocate(n)
++      */
++      static pointer
++      allocate(allocator_type& __a, size_type __n)
++      { return __a.allocate(__n); }
++
++      /**
++       *  @brief  Allocate memory.
++       *  @param  __a  An allocator.
++       *  @param  __n  The number of objects to allocate space for.
++       *  @param  __hint Aid to locality.
++       *  @return Memory of suitable size and alignment for @a n objects
++       *          of type @c value_type
++       *
++       *  Returns <tt> a.allocate(n, hint) </tt>
++      */
++      static pointer
++      allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
++      { return __a.allocate(__n, __hint); }
++
++      /**
++       *  @brief  Deallocate memory.
++       *  @param  __a  An allocator.
++       *  @param  __p  Pointer to the memory to deallocate.
++       *  @param  __n  The number of objects space was allocated for.
++       *
++       *  Calls <tt> a.deallocate(p, n) </tt>
++      */
++      static void
++      deallocate(allocator_type& __a, pointer __p, size_type __n)
++      { __a.deallocate(__p, __n); }
++
++      /**
++       *  @brief  Construct an object of type @a _Up
++       *  @param  __a  An allocator.
++       *  @param  __p  Pointer to memory of suitable size and alignment for Tp
++       *  @param  __args Constructor arguments.
++       *
++       *  Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
++      */
++      template<typename _Up, typename... _Args>
++	static void
++	construct(allocator_type& __a, _Up* __p, _Args&&... __args)
++	{ __a.construct(__p, std::forward<_Args>(__args)...); }
++
++      /**
++       *  @brief  Destroy an object of type @a _Up
++       *  @param  __a  An allocator.
++       *  @param  __p  Pointer to the object to destroy
++       *
++       *  Calls @c __a.destroy(__p).
++      */
++      template<typename _Up>
++	static void
++	destroy(allocator_type& __a, _Up* __p)
++	{ __a.destroy(__p); }
++
++      /**
++       *  @brief  The maximum supported allocation size
++       *  @param  __a  An allocator.
++       *  @return @c __a.max_size()
++      */
++      static size_type
++      max_size(const allocator_type& __a) noexcept
++      { return __a.max_size(); }
++
++      /**
++       *  @brief  Obtain an allocator to use when copying a container.
++       *  @param  __rhs  An allocator.
++       *  @return @c __rhs
++      */
++      static allocator_type
++      select_on_container_copy_construction(const allocator_type& __rhs)
++      { return __rhs; }
++    };
++
++
+   template<typename _Alloc>
+     inline void
+     __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
+--- a/libstdc++-v3/include/bits/basic_string.h	2015-11-25 17:11:33.000000000 +0100
++++ b/libstdc++-v3/include/bits/basic_string.h	2016-02-16 15:24:28.231617711 +0100
+@@ -322,7 +322,6 @@
+       template<class _Iterator>
+         static void
+         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
+-	_GLIBCXX_NOEXCEPT
+         {
+ 	  for (; __k1 != __k2; ++__k1, ++__p)
+ 	    traits_type::assign(*__p, *__k1); // These types are off.
+@@ -2782,7 +2781,6 @@
+       template<class _Iterator>
+         static void
+         _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
+-	_GLIBCXX_NOEXCEPT
+         {
+ 	  for (; __k1 != __k2; ++__k1, ++__p)
+ 	    traits_type::assign(*__p, *__k1); // These types are off.
+--- a/libstdc++-v3/include/bits/c++0x_warning.h	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/bits/c++0x_warning.h	2016-02-16 15:17:37.913515585 +0100
+@@ -29,9 +29,9 @@
+ #define _CXX0X_WARNING_H 1
+ 
+ #if __cplusplus < 201103L
+-#error This file requires compiler and library support for the \
+-ISO C++ 2011 standard. This support is currently experimental, and must be \
+-enabled with the -std=c++11 or -std=gnu++11 compiler options.
++#error This file requires compiler and library support \
++for the ISO C++ 2011 standard. This support must be enabled \
++with the -std=c++11 or -std=gnu++11 compiler options.
+ #endif
+ 
+ #endif
+--- a/libstdc++-v3/include/bits/c++config	2015-03-20 14:26:55.000000000 +0100
++++ b/libstdc++-v3/include/bits/c++config	2016-02-16 15:00:57.786515265 +0100
+@@ -294,7 +294,7 @@
+ # endif
+ 
+ # if _GLIBCXX_USE_CXX11_ABI
+-  inline namespace __cxx11 __attribute__((__abi_tag__)) { }
++  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+ # endif
+   }
+ 
+--- a/libstdc++-v3/include/bits/forward_list.h	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/bits/forward_list.h	2016-02-16 15:09:05.791852030 +0100
+@@ -463,7 +463,8 @@
+ 
+       /**
+        *  @brief  Creates a %forward_list with default constructed elements.
+-       *  @param  __n  The number of elements to initially create.
++       *  @param  __n   The number of elements to initially create.
++       *  @param  __al  An allocator object.
+        *
+        *  This constructor creates the %forward_list with @a __n default
+        *  constructed elements.
+@@ -1083,6 +1084,7 @@
+        *  after @a __pos in constant time.
+        *
+        *  Undefined if @a __pos is in (__before,__last).
++       *  @{
+        */
+       void
+       splice_after(const_iterator __pos, forward_list&&,
+@@ -1093,6 +1095,7 @@
+       splice_after(const_iterator __pos, forward_list&,
+                    const_iterator __before, const_iterator __last)
+       { _M_splice_after(__pos, __before, __last); }
++      // @}
+ 
+       /**
+        *  @brief  Remove all elements equal to value.
+--- a/libstdc++-v3/include/bits/locale_facets_nonio.h	2015-01-20 12:50:51.000000000 +0100
++++ b/libstdc++-v3/include/bits/locale_facets_nonio.h	2016-02-16 15:09:05.792852052 +0100
+@@ -709,7 +709,7 @@
+        *
+        *  @param __s        Start of string to parse.
+        *  @param __end      End of string to parse.
+-       *  @param __io       Source of the locale.
++       *  @param __f        Source of the locale.
+        *  @param __err      Error flags to set.
+        *  @param __tm       Pointer to struct tm to fill in.
+        *  @param __format   Format specifier.
+--- a/libstdc++-v3/include/bits/regex_executor.tcc	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/bits/regex_executor.tcc	2016-02-16 15:11:31.213978569 +0100
+@@ -147,7 +147,10 @@
+     bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+     _M_lookahead(_State<_TraitsT> __state)
+     {
+-      _ResultsVec __what(_M_cur_results.size());
++      // Backreferences may refer to captured content.
++      // We may want to make this faster by not copying,
++      // but let's not be clever prematurely.
++      _ResultsVec __what(_M_cur_results);
+       _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags);
+       __sub._M_states._M_start = __state._M_alt;
+       if (__sub._M_search_from_first())
+--- a/libstdc++-v3/include/bits/shared_ptr_base.h	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/bits/shared_ptr_base.h	2016-02-16 15:02:04.148780336 +0100
+@@ -1540,19 +1540,25 @@
+ 	_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
+ 	{ _M_weak_this._M_assign(__p, __n); }
+ 
+-      template<typename _Tp1>
++      template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
+ 	friend void
+-	__enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
+-					 const __enable_shared_from_this* __pe,
+-					 const _Tp1* __px) noexcept
+-	{
+-	  if (__pe != 0)
+-	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
+-	}
++	__enable_shared_from_this_helper(const __shared_count<_Lp1>&,
++					 const __enable_shared_from_this<_Tp1,
++					 _Lp1>*, const _Tp2*) noexcept;
+ 
+       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
+     };
+ 
++  template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
++    inline void
++    __enable_shared_from_this_helper(const __shared_count<_Lp1>& __pn,
++				     const __enable_shared_from_this<_Tp1,
++				     _Lp1>* __pe,
++				     const _Tp2* __px) noexcept
++    {
++      if (__pe != nullptr)
++	__pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
++    }
+ 
+   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
+     inline __shared_ptr<_Tp, _Lp>
+--- a/libstdc++-v3/include/bits/shared_ptr.h	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/bits/shared_ptr.h	2016-02-16 15:02:04.148780336 +0100
+@@ -582,19 +582,25 @@
+ 	_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
+ 	{ _M_weak_this._M_assign(__p, __n); }
+ 
+-      template<typename _Tp1>
++      template<typename _Tp1, typename _Tp2>
+ 	friend void
+-	__enable_shared_from_this_helper(const __shared_count<>& __pn,
+-					 const enable_shared_from_this* __pe,
+-					 const _Tp1* __px) noexcept
+-	{
+-	  if (__pe != 0)
+-	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
+-	}
++	__enable_shared_from_this_helper(const __shared_count<>&,
++					 const enable_shared_from_this<_Tp1>*,
++					 const _Tp2*) noexcept;
+ 
+       mutable weak_ptr<_Tp>  _M_weak_this;
+     };
+ 
++  template<typename _Tp1, typename _Tp2>
++    inline void
++    __enable_shared_from_this_helper(const __shared_count<>& __pn,
++				     const enable_shared_from_this<_Tp1>*
++				     __pe, const _Tp2* __px) noexcept
++    {
++      if (__pe != nullptr)
++	__pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
++    }
++
+   /**
+    *  @brief  Create an object that is owned by a shared_ptr.
+    *  @param  __a     An allocator.
+--- a/libstdc++-v3/include/bits/valarray_before.h	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/bits/valarray_before.h	2016-02-16 15:37:14.613642837 +0100
+@@ -331,14 +331,24 @@
+       { return pow(__x, __y); }
+   };
+ 
++  template<typename _Tp, bool _IsValidValarrayValue = !__is_abstract(_Tp)>
++    struct __fun_with_valarray
++    {
++      typedef _Tp result_type;
++    };
++
++  template<typename _Tp>
++    struct __fun_with_valarray<_Tp, false>
++    {
++      // No result type defined for invalid value types.
++    };
+ 
+   // We need these bits in order to recover the return type of
+   // some functions/operators now that we're no longer using
+   // function templates.
+   template<typename, typename _Tp>
+-    struct __fun
++    struct __fun : __fun_with_valarray<_Tp>
+     {
+-      typedef _Tp result_type;
+     };
+ 
+   // several specializations for relational operators.
+--- a/libstdc++-v3/include/c_global/cmath	2015-11-24 14:25:07.000000000 +0100
++++ b/libstdc++-v3/include/c_global/cmath	2016-02-16 15:27:06.419691445 +0100
+@@ -880,7 +880,11 @@
+     signbit(_Tp __f)
+     {
+       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+-      return __builtin_signbit(__type(__f));
++      return sizeof(__type) == sizeof(float)
++	? __builtin_signbitf(__type(__f))
++	: sizeof(__type) == sizeof(double)
++	? __builtin_signbit(__type(__f))
++	: __builtin_signbitl(__type(__f));
+     }
+ 
+   template<typename _Tp>
+--- a/libstdc++-v3/include/debug/vector	2015-04-28 19:54:13.000000000 +0200
++++ b/libstdc++-v3/include/debug/vector	2016-02-16 15:09:05.792852052 +0100
+@@ -37,9 +37,12 @@
+ 
+ namespace __gnu_debug
+ {
+-  /// Special vector safe base class to add a guaranteed capacity information
+-  /// useful to detect code relying on the libstdc++ reallocation management
+-  /// implementation detail.
++  /** @brief Base class for Debug Mode vector.
++   *
++   * Adds information about the guaranteed capacity, which is useful for
++   * detecting code which relies on non-portable implementation details of
++   * the libstdc++ reallocation policy.
++   */
+   template<typename _SafeSequence,
+ 	   typename _BaseSequence>
+     class _Safe_vector
+--- a/libstdc++-v3/include/experimental/fs_fwd.h	2015-08-18 19:58:22.000000000 +0200
++++ b/libstdc++-v3/include/experimental/fs_fwd.h	2016-02-16 15:09:05.792852052 +0100
+@@ -22,8 +22,9 @@
+ // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ // <http://www.gnu.org/licenses/>.
+ 
+-/** @file experimental/filesystem
+- *  This is a TS C++ Library header.
++/** @file experimental/fs_fwd.h
++ *  This is an internal header file, included by other library headers.
++ *  Do not attempt to use it directly. @headername{experimental/filesystem}
+  */
+ 
+ #ifndef _GLIBCXX_EXPERIMENTAL_FS_FWD_H
+@@ -52,7 +53,7 @@
+ #endif
+ 
+   /**
+-   * @defgroup filesystem
++   * @defgroup filesystem Filesystem
+    * @ingroup experimental
+    *
+    * Utilities for performing operations on file systems and their components,
+--- a/libstdc++-v3/include/experimental/fs_ops.h	2015-08-18 19:58:22.000000000 +0200
++++ b/libstdc++-v3/include/experimental/fs_ops.h	2016-02-16 15:09:05.792852052 +0100
+@@ -22,8 +22,9 @@
+ // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ // <http://www.gnu.org/licenses/>.
+ 
+-/** @file experimental/filesystem
+- *  This is a TS C++ Library header.
++/** @file experimental/fs_fwd.h
++ *  This is an internal header file, included by other library headers.
++ *  Do not attempt to use it directly. @headername{experimental/filesystem}
+  */
+ 
+ #ifndef _GLIBCXX_EXPERIMENTAL_FS_OPS_H
+--- a/libstdc++-v3/include/experimental/fs_path.h	2015-10-07 23:00:50.000000000 +0200
++++ b/libstdc++-v3/include/experimental/fs_path.h	2016-02-16 15:01:29.895127798 +0100
+@@ -549,16 +549,6 @@
+     std::string _M_what = _M_gen_what();
+   };
+ 
+-  struct path::_Cmpt : path
+-  {
+-    _Cmpt(string_type __s, _Type __t, size_t __pos)
+-      : path(std::move(__s), __t), _M_pos(__pos) { }
+-
+-    _Cmpt() : _M_pos(-1) { }
+-
+-    size_t _M_pos;
+-  };
+-
+   template<>
+     struct path::__is_encoded_char<char> : std::true_type
+     { using value_type = char; };
+@@ -575,6 +565,16 @@
+     struct path::__is_encoded_char<char32_t> : std::true_type
+     { using value_type = char32_t; };
+ 
++  struct path::_Cmpt : path
++  {
++    _Cmpt(string_type __s, _Type __t, size_t __pos)
++      : path(std::move(__s), __t), _M_pos(__pos) { }
++
++    _Cmpt() : _M_pos(-1) { }
++
++    size_t _M_pos;
++  };
++
+   // specialize _Cvt for degenerate 'noconv' case
+   template<>
+     struct path::_Cvt<path::value_type>
+--- a/libstdc++-v3/include/experimental/optional	2015-01-20 12:51:03.000000000 +0100
++++ b/libstdc++-v3/include/experimental/optional	2016-02-16 15:09:05.792852052 +0100
+@@ -33,6 +33,12 @@
+  * @defgroup experimental Experimental
+  *
+  * Components specified by various Technical Specifications.
++ *
++ * As indicated by the std::experimental namespace and the  header paths,
++ * the contents of these Technical Specifications are experimental and not
++ * part of the C++ standard. As such the interfaces and implementations may
++ * change in the future, and there is <STRONG> no guarantee of compatibility
++ * between different GCC releases </STRONG> for these features.
+  */
+ 
+ #if __cplusplus <= 201103L
+--- a/libstdc++-v3/include/experimental/string_view	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/experimental/string_view	2016-02-16 15:09:05.792852052 +0100
+@@ -23,7 +23,7 @@
+ // <http://www.gnu.org/licenses/>.
+ 
+ /** @file experimental/string_view
+- *  This is a Standard C++ Library header.
++ *  This is a TS C++ Library header.
+  */
+ 
+ //
+--- a/libstdc++-v3/include/experimental/string_view.tcc	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/experimental/string_view.tcc	2016-02-16 15:09:05.792852052 +0100
+@@ -24,7 +24,7 @@
+ 
+ /** @file experimental/string_view.tcc
+  *  This is an internal header file, included by other library headers.
+- *  Do not attempt to use it directly. @headername{string_view}
++ *  Do not attempt to use it directly. @headername{experimental/string_view}
+  */
+ 
+ //
+--- a/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp	2016-02-16 15:09:05.793852074 +0100
+@@ -166,13 +166,8 @@
+ 	     class Node_Update,
+ 	     class Node,
+ 	     typename _Alloc>
+-    struct bin_search_tree_traits<
+-      Key,
+-      null_type,
+-      Cmp_Fn,
+-      Node_Update,
+-      Node,
+-      _Alloc>
++    struct
++    bin_search_tree_traits<Key, null_type, Cmp_Fn, Node_Update, Node, _Alloc>
+     {
+     private:
+       typedef types_traits<Key, null_type, _Alloc, false> type_traits;
+--- a/libstdc++-v3/include/std/bitset	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/std/bitset	2016-02-16 15:09:05.793852074 +0100
+@@ -663,7 +663,7 @@
+     };
+ 
+ #if __cplusplus >= 201103L
+-  template<size_t _Nb, bool = _Nb < _GLIBCXX_BITSET_BITS_PER_ULL>
++  template<size_t _Nb, bool = (_Nb < _GLIBCXX_BITSET_BITS_PER_ULL)>
+     struct _Sanitize_val
+     {
+       static constexpr unsigned long long
+@@ -681,8 +681,6 @@
+ #endif
+ 
+   /**
+-   *  @class bitset <bitset>
+-   *
+    *  @brief The %bitset class represents a @e fixed-size sequence of bits.
+    *  @ingroup utilities
+    *
+--- a/libstdc++-v3/include/std/functional	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/std/functional	2016-02-16 15:24:14.452348979 +0100
+@@ -1122,7 +1122,7 @@
+ 
+       // Call unqualified
+       template<typename... _Args, typename _Result
+-	= decltype( std::declval<_Functor>()(
++	= decltype( std::declval<_Functor&>()(
+ 	      _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
+ 				  std::declval<tuple<_Args...>&>() )... ) )>
+ 	_Result
+@@ -1136,7 +1136,7 @@
+       // Call as const
+       template<typename... _Args, typename _Result
+ 	= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
+-		       typename add_const<_Functor>::type>::type>()(
++		       typename add_const<_Functor>::type&>::type>()(
+ 	      _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
+ 				  std::declval<tuple<_Args...>&>() )... ) )>
+ 	_Result
+@@ -1150,7 +1150,7 @@
+       // Call as volatile
+       template<typename... _Args, typename _Result
+ 	= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
+-                       typename add_volatile<_Functor>::type>::type>()(
++                       typename add_volatile<_Functor>::type&>::type>()(
+ 	      _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
+ 				  std::declval<tuple<_Args...>&>() )... ) )>
+ 	_Result
+@@ -1164,7 +1164,7 @@
+       // Call as const volatile
+       template<typename... _Args, typename _Result
+ 	= decltype( std::declval<typename enable_if<(sizeof...(_Args) >= 0),
+-                       typename add_cv<_Functor>::type>::type>()(
++                       typename add_cv<_Functor>::type&>::type>()(
+ 	      _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
+ 				  std::declval<tuple<_Args...>&>() )... ) )>
+ 	_Result
+@@ -1883,7 +1883,7 @@
+       static _Res
+       _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
+       {
+-	return __callable_functor(**_Base::_M_get_pointer(__functor))(
++	return std::__callable_functor(**_Base::_M_get_pointer(__functor))(
+ 	      std::forward<_ArgTypes>(__args)...);
+       }
+     };
+@@ -1898,7 +1898,7 @@
+       static void
+       _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
+       {
+-	__callable_functor(**_Base::_M_get_pointer(__functor))(
++	std::__callable_functor(**_Base::_M_get_pointer(__functor))(
+ 	    std::forward<_ArgTypes>(__args)...);
+       }
+     };
+@@ -1977,19 +1977,14 @@
+     {
+       typedef _Res _Signature_type(_ArgTypes...);
+ 
+-      template<typename _Functor>
+-	using _Invoke = decltype(__callable_functor(std::declval<_Functor&>())
+-				 (std::declval<_ArgTypes>()...) );
++      template<typename _Func,
++	       typename _Res2 = typename result_of<_Func(_ArgTypes...)>::type>
++	struct _Callable : __check_func_return_type<_Res2, _Res> { };
+ 
+       // Used so the return type convertibility checks aren't done when
+       // performing overload resolution for copy construction/assignment.
+       template<typename _Tp>
+-	using _NotSelf = __not_<is_same<_Tp, function>>;
+-
+-      template<typename _Functor>
+-	using _Callable
+-	  = __and_<_NotSelf<_Functor>,
+-		   __check_func_return_type<_Invoke<_Functor>, _Res>>;
++	struct _Callable<function, _Tp> : false_type { };
+ 
+       template<typename _Cond, typename _Tp>
+ 	using _Requires = typename enable_if<_Cond::value, _Tp>::type;
+@@ -2054,6 +2049,7 @@
+        *  reference_wrapper<F>, this function will not throw.
+        */
+       template<typename _Functor,
++	       typename = _Requires<__not_<is_same<_Functor, function>>, void>,
+ 	       typename = _Requires<_Callable<_Functor>, void>>
+ 	function(_Functor);
+ 
+@@ -2246,7 +2242,7 @@
+     }
+ 
+   template<typename _Res, typename... _ArgTypes>
+-    template<typename _Functor, typename>
++    template<typename _Functor, typename, typename>
+       function<_Res(_ArgTypes...)>::
+       function(_Functor __f)
+       : _Function_base()
+--- a/libstdc++-v3/include/std/mutex	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/std/mutex	2016-02-16 15:09:05.793852074 +0100
+@@ -114,7 +114,7 @@
+    * @{
+    */
+ 
+-  /// mutex
++  /// The standard mutex type.
+   class mutex : private __mutex_base
+   {
+   public:
+@@ -158,7 +158,7 @@
+     { return &_M_mutex; }
+   };
+ 
+-  /// recursive_mutex
++  /// The standard recursive mutex type.
+   class recursive_mutex : private __recursive_mutex_base
+   {
+   public:
+@@ -243,7 +243,7 @@
+ 	}
+     };
+ 
+-  /// timed_mutex
++  /// The standard timed mutex type.
+   class timed_mutex
+   : private __mutex_base, public __timed_mutex_impl<timed_mutex>
+   {
+@@ -295,7 +295,7 @@
+     { return &_M_mutex; }
+   };
+ 
+-  /// recursive_timed_mutex
++  /// The standard recursive timed mutex type.
+   class recursive_timed_mutex
+   : private __recursive_mutex_base,
+     public __timed_mutex_impl<recursive_timed_mutex>
+@@ -360,13 +360,22 @@
+   /// and manage it.
+   struct adopt_lock_t { };
+ 
++  /// Tag used to prevent a scoped lock from acquiring ownership of a mutex.
+   constexpr defer_lock_t	defer_lock { };
++
++  /// Tag used to prevent a scoped lock from blocking if a mutex is locked.
+   constexpr try_to_lock_t	try_to_lock { };
++
++  /// Tag used to make a scoped lock take ownership of a locked mutex.
+   constexpr adopt_lock_t	adopt_lock { };
+ 
+-  /// @brief  Scoped lock idiom.
+-  // Acquire the mutex here with a constructor call, then release with
+-  // the destructor call in accordance with RAII style.
++  /** @brief A movable scoped lock type.
++   *
++   * A unique_lock controls mutex ownership within a scope. Ownership of the
++   * mutex can be delayed until after construction and can be transferred
++   * to another unique_lock by move construction or move assignment. If a
++   * mutex lock is owned when the destructor runs ownership will be released.
++   */
+   template<typename _Mutex>
+     class lock_guard
+     {
+--- a/libstdc++-v3/include/tr2/dynamic_bitset	2015-01-05 13:33:28.000000000 +0100
++++ b/libstdc++-v3/include/tr2/dynamic_bitset	2016-02-16 15:09:05.793852074 +0100
+@@ -593,6 +593,9 @@
+        *  @param  __str  A string of '0' and '1' characters.
+        *  @param  __pos  Index of the first character in @p __str to use.
+        *  @param  __n    The number of characters to copy.
++       *  @param  __zero The character to use for unset bits.
++       *  @param  __one  The character to use for set bits.
++       *  @param  __alloc An allocator.
+        *  @throw  std::out_of_range  If @p __pos is bigger the size of @p __str.
+        *  @throw  std::invalid_argument  If a character appears in the string
+        *                                 which is neither '0' nor '1'.
+--- a/libstdc++-v3/src/c++11/futex.cc	2015-03-23 17:47:18.000000000 +0100
++++ b/libstdc++-v3/src/c++11/futex.cc	2016-02-16 15:12:51.420663390 +0100
+@@ -52,7 +52,7 @@
+ 	// we will fall back to spin-waiting.  The only thing we could do
+ 	// here on errors is abort.
+ 	int ret __attribute__((unused));
+-	ret = syscall (SYS_futex, __addr, futex_wait_op, __val);
++	ret = syscall (SYS_futex, __addr, futex_wait_op, __val, nullptr);
+ 	_GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN);
+ 	return true;
+       }
+--- a/wgetpatch	1970-01-01 01:00:00.000000000 +0100
++++ b/wgetpatch	2016-02-16 15:10:55.439218657 +0100
+@@ -0,0 +1,3 @@
++#!/bin/bash -e
++
++wget "$1" -O - | patch -Np1 -i -

Added: trunk/glibc/glibc-2.22-upstream_fixes-1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/glibc/glibc-2.22-upstream_fixes-1.patch	Tue Feb 16 14:59:58 2016	(r3355)
@@ -0,0 +1,1434 @@
+Submitted By:            Armin K. <krejzi at email dot com>
+Date:                    2016-02-16
+Initial Package Version: 2.22
+Upstream Status:         Committed
+Origin:                  Upstream
+Description:             Various fixes identified upstream
+
+--- a/catgets/catgets.c	2015-08-05 08:42:21.000000000 +0200
++++ b/catgets/catgets.c	2016-02-16 18:13:26.984538556 +0100
+@@ -16,7 +16,6 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <alloca.h>
+ #include <errno.h>
+ #include <locale.h>
+ #include <nl_types.h>
+@@ -35,6 +34,7 @@
+   __nl_catd result;
+   const char *env_var = NULL;
+   const char *nlspath = NULL;
++  char *tmp = NULL;
+ 
+   if (strchr (cat_name, '/') == NULL)
+     {
+@@ -54,7 +54,10 @@
+ 	{
+ 	  /* Append the system dependent directory.  */
+ 	  size_t len = strlen (nlspath) + 1 + sizeof NLSPATH;
+-	  char *tmp = alloca (len);
++	  tmp = malloc (len);
++
++	  if (__glibc_unlikely (tmp == NULL))
++	    return (nl_catd) -1;
+ 
+ 	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
+ 	  nlspath = tmp;
+@@ -65,16 +68,18 @@
+ 
+   result = (__nl_catd) malloc (sizeof (*result));
+   if (result == NULL)
+-    /* We cannot get enough memory.  */
+-    return (nl_catd) -1;
+-
+-  if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
++    {
++      /* We cannot get enough memory.  */
++      result = (nl_catd) -1;
++    }
++  else if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
+     {
+       /* Couldn't open the file.  */
+       free ((void *) result);
+-      return (nl_catd) -1;
++      result = (nl_catd) -1;
+     }
+ 
++  free (tmp);
+   return (nl_catd) result;
+ }
+ 
+--- a/catgets/open_catalog.c	2015-08-05 08:42:21.000000000 +0200
++++ b/catgets/open_catalog.c	2016-02-16 18:13:26.985538577 +0100
+@@ -47,6 +47,7 @@
+   size_t tab_size;
+   const char *lastp;
+   int result = -1;
++  char *buf = NULL;
+ 
+   if (strchr (cat_name, '/') != NULL || nlspath == NULL)
+     fd = open_not_cancel_2 (cat_name, O_RDONLY);
+@@ -57,23 +58,23 @@
+   if (__glibc_unlikely (bufact + (n) >= bufmax))			      \
+     {									      \
+       char *old_buf = buf;						      \
+-      bufmax += 256 + (n);						      \
+-      buf = (char *) alloca (bufmax);					      \
+-      memcpy (buf, old_buf, bufact);					      \
++      bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax;		      \
++      buf = realloc (buf, bufmax);					      \
++      if (__glibc_unlikely (buf == NULL))				      \
++	{								      \
++	  free (old_buf);						      \
++	  return -1;							      \
++	}								      \
+     }
+ 
+       /* The RUN_NLSPATH variable contains a colon separated list of
+ 	 descriptions where we expect to find catalogs.  We have to
+ 	 recognize certain % substitutions and stop when we found the
+ 	 first existing file.  */
+-      char *buf;
+       size_t bufact;
+-      size_t bufmax;
++      size_t bufmax = 0;
+       size_t len;
+ 
+-      buf = NULL;
+-      bufmax = 0;
+-
+       fd = -1;
+       while (*run_nlspath != '\0')
+ 	{
+@@ -188,7 +189,10 @@
+ 
+   /* Avoid dealing with directories and block devices */
+   if (__builtin_expect (fd, 0) < 0)
+-    return -1;
++    {
++      free (buf);
++      return -1;
++    }
+ 
+   if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0)
+     goto close_unlock_return;
+@@ -325,6 +329,7 @@
+   /* Release the lock again.  */
+  close_unlock_return:
+   close_not_cancel_no_status (fd);
++  free (buf);
+ 
+   return result;
+ }
+--- a/elf/dl-close.c	2015-08-05 08:42:21.000000000 +0200
++++ b/elf/dl-close.c	2016-02-16 18:13:26.985538577 +0100
+@@ -144,6 +144,14 @@
+   char done[nloaded];
+   struct link_map *maps[nloaded];
+ 
++  /* Clear DF_1_NODELETE to force object deletion.  We don't need to touch
++     l_tls_dtor_count because forced object deletion only happens when an
++     error occurs during object load.  Destructor registration for TLS
++     non-POD objects should not have happened till then for this
++     object.  */
++  if (force)
++    map->l_flags_1 &= ~DF_1_NODELETE;
++
+   /* Run over the list and assign indexes to the link maps and enter
+      them into the MAPS array.  */
+   int idx = 0;
+@@ -153,13 +161,6 @@
+       maps[idx] = l;
+       ++idx;
+ 
+-      /* Clear DF_1_NODELETE to force object deletion.  We don't need to touch
+-	 l_tls_dtor_count because forced object deletion only happens when an
+-	 error occurs during object load.  Destructor registration for TLS
+-	 non-POD objects should not have happened till then for this
+-	 object.  */
+-      if (force)
+-	l->l_flags_1 &= ~DF_1_NODELETE;
+     }
+   assert (idx == nloaded);
+ 
+--- a/elf/dl-load.c	2015-08-05 08:42:21.000000000 +0200
++++ b/elf/dl-load.c	2016-02-16 18:13:26.985538577 +0100
+@@ -42,6 +42,7 @@
+ #include <dl-map-segments.h>
+ #include <dl-unmap-segments.h>
+ #include <dl-machine-reject-phdr.h>
++#include <dl-sysdep-open.h>
+ 
+ 
+ #include <endian.h>
+@@ -1471,9 +1472,13 @@
+    ignore only ELF files for other architectures.  Non-ELF files and
+    ELF files with different header information cause fatal errors since
+    this could mean there is something wrong in the installation and the
+-   user might want to know about this.  */
++   user might want to know about this.
++
++   If FD is not -1, then the file is already open and FD refers to it.
++   In that case, FD is consumed for both successful and error returns.  */
+ static int
+-open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
++open_verify (const char *name, int fd,
++             struct filebuf *fbp, struct link_map *loader,
+ 	     int whatcode, int mode, bool *found_other_class, bool free_name)
+ {
+   /* This is the expected ELF header.  */
+@@ -1514,6 +1519,7 @@
+   if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
+       && loader->l_auditing == 0)
+     {
++      const char *original_name = name;
+       struct audit_ifaces *afct = GLRO(dl_audit);
+       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+ 	{
+@@ -1528,11 +1534,21 @@
+ 
+ 	  afct = afct->next;
+ 	}
++
++      if (fd != -1 && name != original_name && strcmp (name, original_name))
++        {
++          /* An audit library changed what we're supposed to open,
++             so FD no longer matches it.  */
++          __close (fd);
++          fd = -1;
++        }
+     }
+ #endif
+ 
+-  /* Open the file.  We always open files read-only.  */
+-  int fd = __open (name, O_RDONLY | O_CLOEXEC);
++  if (fd == -1)
++    /* Open the file.  We always open files read-only.  */
++    fd = __open (name, O_RDONLY | O_CLOEXEC);
++
+   if (fd != -1)
+     {
+       ElfW(Ehdr) *ehdr;
+@@ -1801,7 +1817,7 @@
+ 	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
+ 	    _dl_debug_printf ("  trying file=%s\n", buf);
+ 
+-	  fd = open_verify (buf, fbp, loader, whatcode, mode,
++	  fd = open_verify (buf, -1, fbp, loader, whatcode, mode,
+ 			    found_other_class, false);
+ 	  if (this_dir->status[cnt] == unknown)
+ 	    {
+@@ -2041,6 +2057,20 @@
+ 			&loader->l_runpath_dirs, &realname, &fb, loader,
+ 			LA_SER_RUNPATH, &found_other_class);
+ 
++      if (fd == -1)
++        {
++          realname = _dl_sysdep_open_object (name, namelen, &fd);
++          if (realname != NULL)
++            {
++              fd = open_verify (realname, fd,
++                                &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
++                                LA_SER_CONFIG, mode, &found_other_class,
++                                false);
++              if (fd == -1)
++                free (realname);
++            }
++        }
++
+ #ifdef USE_LDCONFIG
+       if (fd == -1
+ 	  && (__glibc_likely ((mode & __RTLD_SECURE) == 0)
+@@ -2086,7 +2116,7 @@
+ 
+ 	      if (cached != NULL)
+ 		{
+-		  fd = open_verify (cached,
++		  fd = open_verify (cached, -1,
+ 				    &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+ 				    LA_SER_CONFIG, mode, &found_other_class,
+ 				    false);
+@@ -2121,7 +2151,7 @@
+ 	fd = -1;
+       else
+ 	{
+-	  fd = open_verify (realname, &fb,
++	  fd = open_verify (realname, -1, &fb,
+ 			    loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
+ 			    &found_other_class, true);
+ 	  if (__glibc_unlikely (fd == -1))
+--- a/elf/dl-lookup.c	2015-08-05 08:42:21.000000000 +0200
++++ b/elf/dl-lookup.c	2016-02-16 18:13:26.985538577 +0100
+@@ -1016,6 +1016,18 @@
+ #ifdef SHARED
+   if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
+     {
++/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
++   LD_TRACE_PRELINKING.  */
++#define RTYPE_CLASS_VALID	8
++#define RTYPE_CLASS_PLT		(8|1)
++#define RTYPE_CLASS_COPY	(8|2)
++#define RTYPE_CLASS_TLS		(8|4)
++#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
++# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
++#endif
++#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
++# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
++#endif
+       int conflict = 0;
+       struct sym_val val = { NULL, NULL };
+ 
+@@ -1071,12 +1083,17 @@
+ 
+       if (value->s)
+ 	{
++	  /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
++	     bits since since prelink only uses them.  */
++	  type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
+ 	  if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
+ 				== STT_TLS))
+-	    type_class = 4;
++	    /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS.  */
++	    type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
+ 	  else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
+ 				     == STT_GNU_IFUNC))
+-	    type_class |= 8;
++	    /* Set the RTYPE_CLASS_VALID bit.  */
++	    type_class |= RTYPE_CLASS_VALID;
+ 	}
+ 
+       if (conflict
+--- a/elf/dl-sysdep-open.h	1970-01-01 01:00:00.000000000 +0100
++++ b/elf/dl-sysdep-open.h	2016-02-16 18:13:26.986538597 +0100
+@@ -0,0 +1,45 @@
++/* System-specific call to open a shared object by name.  Stub version.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#ifndef _DL_SYSDEP_OPEN_H
++#define _DL_SYSDEP_OPEN_H	1
++
++#include <assert.h>
++#include <stddef.h>
++
++/* NAME is a name without slashes, as it appears in a DT_NEEDED entry
++   or a dlopen call's argument or suchlike.  NAMELEN is (strlen (NAME) + 1).
++
++   Find NAME in an OS-dependent fashion, and return its "real" name.
++   Optionally fill in *FD with a file descriptor open on that file (or
++   else leave its initial value of -1).  The return value is a new
++   malloc'd string, which will be free'd by the caller.  If NAME is
++   resolved to an actual file that can be opened, then the return
++   value should name that file (and if *FD was not set, then a normal
++   __open call on that string will be made).  If *FD was set by some
++   other means than a normal open and there is no "real" name to use,
++   then __strdup (NAME) is fine (modulo error checking).  */
++
++static inline char *
++_dl_sysdep_open_object (const char *name, size_t namelen, int *fd)
++{
++  assert (*fd == -1);
++  return NULL;
++}
++
++#endif  /* dl-sysdep-open.h */
+--- a/elf/rtld.c	2015-08-05 08:42:21.000000000 +0200
++++ b/elf/rtld.c	2016-02-16 18:13:26.986538597 +0100
+@@ -162,7 +162,6 @@
+     ._dl_hwcap_mask = HWCAP_IMPORTANT,
+     ._dl_lazy = 1,
+     ._dl_fpu_control = _FPU_DEFAULT,
+-    ._dl_pointer_guard = 1,
+     ._dl_pagesize = EXEC_PAGESIZE,
+     ._dl_inhibit_cache = 0,
+ 
+@@ -709,15 +708,12 @@
+ #endif
+ 
+   /* Set up the pointer guard as well, if necessary.  */
+-  if (GLRO(dl_pointer_guard))
+-    {
+-      uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
+-							     stack_chk_guard);
++  uintptr_t pointer_chk_guard
++    = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
+ #ifdef THREAD_SET_POINTER_GUARD
+-      THREAD_SET_POINTER_GUARD (pointer_chk_guard);
++  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+ #endif
+-      __pointer_chk_guard_local = pointer_chk_guard;
+-    }
++  __pointer_chk_guard_local = pointer_chk_guard;
+ 
+   /* We do not need the _dl_random value anymore.  The less
+      information we leave behind, the better, so clear the
+@@ -2471,9 +2467,6 @@
+ 	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+ 	      break;
+ 	    }
+-
+-	  if (memcmp (envline, "POINTER_GUARD", 13) == 0)
+-	    GLRO(dl_pointer_guard) = envline[14] != '0';
+ 	  break;
+ 
+ 	case 14:
+--- a/locale/categories.def	2015-08-05 08:42:21.000000000 +0200
++++ b/locale/categories.def	2016-02-16 18:13:26.986538597 +0100
+@@ -58,7 +58,6 @@
+   DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB,        "collate-collseqmb",        std, wstring)
+   DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC,        "collate-collseqwc",        std, wstring)
+   DEFINE_ELEMENT (_NL_COLLATE_CODESET,		"collate-codeset",	    std, string)
+-  DEFINE_ELEMENT (_NL_COLLATE_ENCODING_TYPE,   "collate-encoding-type",    std, word)
+   ), NO_POSTLOAD)
+ 
+ 
+--- a/locale/C-collate.c	2015-08-05 08:42:21.000000000 +0200
++++ b/locale/C-collate.c	2016-02-16 18:13:26.986538597 +0100
+@@ -144,8 +144,6 @@
+     /* _NL_COLLATE_COLLSEQWC */
+     { .string = (const char *) collseqwc },
+     /* _NL_COLLATE_CODESET */
+-    { .string = _nl_C_codeset },
+-    /* _NL_COLLATE_ENCODING_TYPE */
+-    { .word = __cet_8bit }
++    { .string = _nl_C_codeset }
+   }
+ };
+--- a/locale/langinfo.h	2015-08-05 08:42:21.000000000 +0200
++++ b/locale/langinfo.h	2016-02-16 18:13:26.986538597 +0100
+@@ -255,7 +255,6 @@
+   _NL_COLLATE_COLLSEQMB,
+   _NL_COLLATE_COLLSEQWC,
+   _NL_COLLATE_CODESET,
+-  _NL_COLLATE_ENCODING_TYPE,
+   _NL_NUM_LC_COLLATE,
+ 
+   /* LC_CTYPE category: character classification.
+--- a/locale/loadlocale.c	2015-08-05 08:42:21.000000000 +0200
++++ b/locale/loadlocale.c	2016-02-16 18:13:26.987538617 +0100
+@@ -121,9 +121,10 @@
+       switch (category)
+ 	{
+ #define CATTEST(cat) \
+-	case LC_##cat:							      \
+-	  assert (cnt < (sizeof (_nl_value_type_LC_##cat)		      \
+-			 / sizeof (_nl_value_type_LC_##cat[0])));	      \
++	case LC_##cat:						\
++	  if (cnt >= (sizeof (_nl_value_type_LC_##cat)		\
++		      / sizeof (_nl_value_type_LC_##cat[0])))	\
++	    goto puntdata;					\
+ 	  break
+ 	  CATTEST (NUMERIC);
+ 	  CATTEST (TIME);
+--- a/locale/localeinfo.h	2015-08-05 08:42:21.000000000 +0200
++++ b/locale/localeinfo.h	2016-02-16 18:13:26.987538617 +0100
+@@ -110,14 +110,6 @@
+   sort_mask
+ };
+ 
+-/* Collation encoding type.  */
+-enum collation_encoding_type
+-{
+-  __cet_other,
+-  __cet_8bit,
+-  __cet_utf8
+-};
+-
+ /* We can map the types of the entries into a few categories.  */
+ enum value_type
+ {
+--- a/locale/programs/ld-collate.c	2015-08-05 08:42:21.000000000 +0200
++++ b/locale/programs/ld-collate.c	2016-02-16 18:13:26.987538617 +0100
+@@ -32,7 +32,6 @@
+ #include "linereader.h"
+ #include "locfile.h"
+ #include "elem-hash.h"
+-#include "../localeinfo.h"
+ 
+ /* Uncomment the following line in the production version.  */
+ /* #define NDEBUG 1 */
+@@ -2131,8 +2130,6 @@
+ 	  /* The words have to be handled specially.  */
+ 	  if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
+ 	    add_locale_uint32 (&file, 0);
+-	  else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE))
+-	    add_locale_uint32 (&file, __cet_other);
+ 	  else
+ 	    add_locale_empty (&file);
+ 	}
+@@ -2496,12 +2493,6 @@
+   add_locale_raw_data (&file, collate->mbseqorder, 256);
+   add_locale_collseq_table (&file, &collate->wcseqorder);
+   add_locale_string (&file, charmap->code_set_name);
+-  if (strcmp (charmap->code_set_name, "UTF-8") == 0)
+-    add_locale_uint32 (&file, __cet_utf8);
+-  else if (charmap->mb_cur_max == 1)
+-    add_locale_uint32 (&file, __cet_8bit);
+-  else
+-    add_locale_uint32 (&file, __cet_other);
+   write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
+ 
+   obstack_free (&weightpool, NULL);
+--- a/math/Makefile	2015-08-05 08:42:21.000000000 +0200
++++ b/math/Makefile	2016-02-16 18:13:26.988538638 +0100
+@@ -98,7 +98,7 @@
+ 	(echo '/* GNU ld script'; echo '*/';\
+ 	 cat $<; \
+ 	 echo 'GROUP ( $(slibdir)/libm.so$(libm.so-version) ' \
+-	      'AS_NEEDED ( $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \
++	      'AS_NEEDED ( $(libdir)/libmvec_nonshared.a $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \
+ 	) > $@
+ endif
+ 
+--- a/misc/hsearch_r.c	2015-08-05 08:42:21.000000000 +0200
++++ b/misc/hsearch_r.c	2016-02-16 18:13:26.988538638 +0100
+@@ -19,7 +19,7 @@
+ #include <errno.h>
+ #include <malloc.h>
+ #include <string.h>
+-
++#include <stdint.h>
+ #include <search.h>
+ 
+ /* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
+@@ -46,15 +46,12 @@
+ isprime (unsigned int number)
+ {
+   /* no even number will be passed */
+-  unsigned int div = 3;
+-
+-  while (div * div < number && number % div != 0)
+-    div += 2;
+-
+-  return number % div != 0;
++  for (unsigned int div = 3; div <= number / div; div += 2)
++    if (number % div == 0)
++      return 0;
++  return 1;
+ }
+ 
+-
+ /* Before using the hash table we must allocate memory for it.
+    Test for an existing table are done. We allocate one element
+    more as the found prime number says. This is done for more effective
+@@ -81,10 +78,19 @@
+      use will not work.  */
+   if (nel < 3)
+     nel = 3;
+-  /* Change nel to the first prime number not smaller as nel. */
+-  nel |= 1;      /* make odd */
+-  while (!isprime (nel))
+-    nel += 2;
++
++  /* Change nel to the first prime number in the range [nel, UINT_MAX - 2],
++     The '- 2' means 'nel += 2' cannot overflow.  */
++  for (nel |= 1; ; nel += 2)
++    {
++      if (UINT_MAX - 2 < nel)
++	{
++	  __set_errno (ENOMEM);
++	  return 0;
++	}
++      if (isprime (nel))
++	break;
++    }
+ 
+   htab->size = nel;
+   htab->filled = 0;
+--- a/misc/mntent_r.c	2015-08-05 08:42:21.000000000 +0200
++++ b/misc/mntent_r.c	2016-02-16 18:13:26.988538638 +0100
+@@ -136,7 +136,9 @@
+       end_ptr = strchr (buffer, '\n');
+       if (end_ptr != NULL)	/* chop newline */
+ 	{
+-	  while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
++	  /* Do not walk past the start of buffer if it's all whitespace.  */
++	  while (end_ptr != buffer
++		 && (end_ptr[-1] == ' ' || end_ptr[-1] == '\t'))
+             end_ptr--;
+ 	  *end_ptr = '\0';
+ 	}
+--- a/misc/regexp.h	2015-08-05 08:42:21.000000000 +0200
++++ b/misc/regexp.h	2016-02-16 18:13:26.988538638 +0100
+@@ -19,10 +19,11 @@
+ #ifndef _REGEXP_H
+ #define _REGEXP_H	1
+ 
+-/* The contents of this header file were standardized in the
+-   Single Unix Specification, Version 2 (1997) but marked as
+-   LEGACY; new applications were already being encouraged to
+-   use <regex.h> instead.  POSIX.1-2001 removed this header.
++/* The contents of this header file were originally standardized in
++   the Single Unix Specification, Issue 3 (1992).  In Issue 4 (1994)
++   the header was marked as TO BE WITHDRAWN, and new applications
++   were encouraged to use <regex.h> instead.  It was officially
++   withdrawn from the standard in Issue 6 (aka POSIX.1-2001).
+ 
+    This header is provided only for backward compatibility.
+    It will be removed in the next release of the GNU C Library.
+--- a/misc/sys/param.h	2015-08-05 08:42:21.000000000 +0200
++++ b/misc/sys/param.h	2016-02-16 18:13:26.988538638 +0100
+@@ -50,6 +50,9 @@
+ #if !defined NOFILE && defined OPEN_MAX
+ # define NOFILE		OPEN_MAX
+ #endif
++#if !defined MAXHOSTNAMELEN && defined HOST_NAME_MAX
++# define MAXHOSTNAMELEN	HOST_NAME_MAX
++#endif
+ #ifndef NCARGS
+ # ifdef ARG_MAX
+ #  define NCARGS	ARG_MAX
+--- a/resolv/nss_dns/dns-host.c	2015-08-05 08:42:21.000000000 +0200
++++ b/resolv/nss_dns/dns-host.c	2016-02-16 18:13:26.989538658 +0100
+@@ -1031,7 +1031,10 @@
+   int h_namelen = 0;
+ 
+   if (ancount == 0)
+-    return NSS_STATUS_NOTFOUND;
++    {
++      *h_errnop = HOST_NOT_FOUND;
++      return NSS_STATUS_NOTFOUND;
++    }
+ 
+   while (ancount-- > 0 && cp < end_of_message && had_error == 0)
+     {
+@@ -1208,7 +1211,14 @@
+   /* Special case here: if the resolver sent a result but it only
+      contains a CNAME while we are looking for a T_A or T_AAAA record,
+      we fail with NOTFOUND instead of TRYAGAIN.  */
+-  return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
++  if (canon != NULL)
++    {
++      *h_errnop = HOST_NOT_FOUND;
++      return NSS_STATUS_NOTFOUND;
++    }
++
++  *h_errnop = NETDB_INTERNAL;
++  return NSS_STATUS_TRYAGAIN;
+ }
+ 
+ 
+@@ -1222,11 +1232,101 @@
+ 
+   enum nss_status status = NSS_STATUS_NOTFOUND;
+ 
++  /* Combining the NSS status of two distinct queries requires some
++     compromise and attention to symmetry (A or AAAA queries can be
++     returned in any order).  What follows is a breakdown of how this
++     code is expected to work and why. We discuss only SUCCESS,
++     TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
++     that apply (though RETURN and MERGE exist).  We make a distinction
++     between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
++     A recoverable TRYAGAIN is almost always due to buffer size issues
++     and returns ERANGE in errno and the caller is expected to retry
++     with a larger buffer.
++
++     Lastly, you may be tempted to make significant changes to the
++     conditions in this code to bring about symmetry between responses.
++     Please don't change anything without due consideration for
++     expected application behaviour.  Some of the synthesized responses
++     aren't very well thought out and sometimes appear to imply that
++     IPv4 responses are always answer 1, and IPv6 responses are always
++     answer 2, but that's not true (see the implemetnation of send_dg
++     and send_vc to see response can arrive in any order, particlarly
++     for UDP). However, we expect it holds roughly enough of the time
++     that this code works, but certainly needs to be fixed to make this
++     a more robust implementation.
++
++     ----------------------------------------------
++     | Answer 1 Status /   | Synthesized | Reason |
++     | Answer 2 Status     | Status      |        |
++     |--------------------------------------------|
++     | SUCCESS/SUCCESS     | SUCCESS     | [1]    |
++     | SUCCESS/TRYAGAIN    | TRYAGAIN    | [5]    |
++     | SUCCESS/TRYAGAIN'   | SUCCESS     | [1]    |
++     | SUCCESS/NOTFOUND    | SUCCESS     | [1]    |
++     | SUCCESS/UNAVAIL     | SUCCESS     | [1]    |
++     | TRYAGAIN/SUCCESS    | TRYAGAIN    | [2]    |
++     | TRYAGAIN/TRYAGAIN   | TRYAGAIN    | [2]    |
++     | TRYAGAIN/TRYAGAIN'  | TRYAGAIN    | [2]    |
++     | TRYAGAIN/NOTFOUND   | TRYAGAIN    | [2]    |
++     | TRYAGAIN/UNAVAIL    | TRYAGAIN    | [2]    |
++     | TRYAGAIN'/SUCCESS   | SUCCESS     | [3]    |
++     | TRYAGAIN'/TRYAGAIN  | TRYAGAIN    | [3]    |
++     | TRYAGAIN'/TRYAGAIN' | TRYAGAIN'   | [3]    |
++     | TRYAGAIN'/NOTFOUND  | TRYAGAIN'   | [3]    |
++     | TRYAGAIN'/UNAVAIL   | UNAVAIL     | [3]    |
++     | NOTFOUND/SUCCESS    | SUCCESS     | [3]    |
++     | NOTFOUND/TRYAGAIN   | TRYAGAIN    | [3]    |
++     | NOTFOUND/TRYAGAIN'  | TRYAGAIN'   | [3]    |
++     | NOTFOUND/NOTFOUND   | NOTFOUND    | [3]    |
++     | NOTFOUND/UNAVAIL    | UNAVAIL     | [3]    |
++     | UNAVAIL/SUCCESS     | UNAVAIL     | [4]    |
++     | UNAVAIL/TRYAGAIN    | UNAVAIL     | [4]    |
++     | UNAVAIL/TRYAGAIN'   | UNAVAIL     | [4]    |
++     | UNAVAIL/NOTFOUND    | UNAVAIL     | [4]    |
++     | UNAVAIL/UNAVAIL     | UNAVAIL     | [4]    |
++     ----------------------------------------------
++
++     [1] If the first response is a success we return success.
++         This ignores the state of the second answer and in fact
++         incorrectly sets errno and h_errno to that of the second
++	 answer.  However because the response is a success we ignore
++	 *errnop and *h_errnop (though that means you touched errno on
++         success).  We are being conservative here and returning the
++         likely IPv4 response in the first answer as a success.
++
++     [2] If the first response is a recoverable TRYAGAIN we return
++	 that instead of looking at the second response.  The
++	 expectation here is that we have failed to get an IPv4 response
++	 and should retry both queries.
++
++     [3] If the first response was not a SUCCESS and the second
++	 response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
++	 or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
++	 result from the second response, otherwise the first responses
++	 status is used.  Again we have some odd side-effects when the
++	 second response is NOTFOUND because we overwrite *errnop and
++	 *h_errnop that means that a first answer of NOTFOUND might see
++	 its *errnop and *h_errnop values altered.  Whether it matters
++	 in practice that a first response NOTFOUND has the wrong
++	 *errnop and *h_errnop is undecided.
++
++     [4] If the first response is UNAVAIL we return that instead of
++	 looking at the second response.  The expectation here is that
++	 it will have failed similarly e.g. configuration failure.
++
++     [5] Testing this code is complicated by the fact that truncated
++	 second response buffers might be returned as SUCCESS if the
++	 first answer is a SUCCESS.  To fix this we add symmetry to
++	 TRYAGAIN with the second response.  If the second response
++	 is a recoverable error we now return TRYAGIN even if the first
++	 response was SUCCESS.  */
++
+   if (anslen1 > 0)
+     status = gaih_getanswer_slice(answer1, anslen1, qname,
+ 				  &pat, &buffer, &buflen,
+ 				  errnop, h_errnop, ttlp,
+ 				  &first);
++
+   if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
+        || (status == NSS_STATUS_TRYAGAIN
+ 	   /* We want to look at the second answer in case of an
+@@ -1242,8 +1342,15 @@
+ 						     &pat, &buffer, &buflen,
+ 						     errnop, h_errnop, ttlp,
+ 						     &first);
++      /* Use the second response status in some cases.  */
+       if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
+ 	status = status2;
++      /* Do not return a truncated second response (unless it was
++         unavoidable e.g. unrecoverable TRYAGAIN).  */
++      if (status == NSS_STATUS_SUCCESS
++	  && (status2 == NSS_STATUS_TRYAGAIN
++	      && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
++	status = NSS_STATUS_TRYAGAIN;
+     }
+ 
+   return status;
+--- a/resolv/res_query.c	2015-08-05 08:42:21.000000000 +0200
++++ b/resolv/res_query.c	2016-02-16 18:13:26.989538658 +0100
+@@ -396,6 +396,7 @@
+ 		  {
+ 		    free (*answerp2);
+ 		    *answerp2 = NULL;
++		    *nanswerp2 = 0;
+ 		    *answerp2_malloced = 0;
+ 		  }
+ 	}
+@@ -447,6 +448,7 @@
+ 			  {
+ 			    free (*answerp2);
+ 			    *answerp2 = NULL;
++			    *nanswerp2 = 0;
+ 			    *answerp2_malloced = 0;
+ 			  }
+ 
+@@ -521,6 +523,7 @@
+ 	  {
+ 	    free (*answerp2);
+ 	    *answerp2 = NULL;
++	    *nanswerp2 = 0;
+ 	    *answerp2_malloced = 0;
+ 	  }
+ 	if (saved_herrno != -1)
+--- a/resolv/res_send.c	2015-08-05 08:42:21.000000000 +0200
++++ b/resolv/res_send.c	2016-02-16 18:13:26.990538679 +0100
+@@ -1,3 +1,20 @@
++/* Copyright (C) 2016 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
+ /*
+  * Copyright (c) 1985, 1989, 1993
+  *    The Regents of the University of California.  All rights reserved.
+@@ -363,6 +380,8 @@
+ #ifdef USE_HOOKS
+ 	if (__glibc_unlikely (statp->qhook || statp->rhook))       {
+ 		if (anssiz < MAXPACKET && ansp) {
++			/* Always allocate MAXPACKET, callers expect
++			   this specific size.  */
+ 			u_char *buf = malloc (MAXPACKET);
+ 			if (buf == NULL)
+ 				return (-1);
+@@ -638,6 +657,77 @@
+     return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
+ }
+ 
++/* The send_vc function is responsible for sending a DNS query over TCP
++   to the nameserver numbered NS from the res_state STATP i.e.
++   EXT(statp).nssocks[ns].  The function supports sending both IPv4 and
++   IPv6 queries at the same serially on the same socket.
++
++   Please note that for TCP there is no way to disable sending both
++   queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
++   and sends the queries serially and waits for the result after each
++   sent query.  This implemetnation should be corrected to honour these
++   options.
++
++   Please also note that for TCP we send both queries over the same
++   socket one after another.  This technically violates best practice
++   since the server is allowed to read the first query, respond, and
++   then close the socket (to service another client).  If the server
++   does this, then the remaining second query in the socket data buffer
++   will cause the server to send the client an RST which will arrive
++   asynchronously and the client's OS will likely tear down the socket
++   receive buffer resulting in a potentially short read and lost
++   response data.  This will force the client to retry the query again,
++   and this process may repeat until all servers and connection resets
++   are exhausted and then the query will fail.  It's not known if this
++   happens with any frequency in real DNS server implementations.  This
++   implementation should be corrected to use two sockets by default for
++   parallel queries.
++
++   The query stored in BUF of BUFLEN length is sent first followed by
++   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
++   serially on the same socket.
++
++   Answers to the query are stored firstly in *ANSP up to a max of
++   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
++   is non-NULL (to indicate that modifying the answer buffer is allowed)
++   then malloc is used to allocate a new response buffer and ANSCP and
++   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
++   are needed but ANSCP is NULL, then as much of the response as
++   possible is read into the buffer, but the results will be truncated.
++   When truncation happens because of a small answer buffer the DNS
++   packets header feild TC will bet set to 1, indicating a truncated
++   message and the rest of the socket data will be read and discarded.
++
++   Answers to the query are stored secondly in *ANSP2 up to a max of
++   *ANSSIZP2 bytes, with the actual response length stored in
++   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
++   is non-NULL (required for a second query) then malloc is used to
++   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
++   size and *ANSP2_MALLOCED is set to 1.
++
++   The ANSP2_MALLOCED argument will eventually be removed as the
++   change in buffer pointer can be used to detect the buffer has
++   changed and that the caller should use free on the new buffer.
++
++   Note that the answers may arrive in any order from the server and
++   therefore the first and second answer buffers may not correspond to
++   the first and second queries.
++
++   It is not supported to call this function with a non-NULL ANSP2
++   but a NULL ANSCP.  Put another way, you can call send_vc with a
++   single unmodifiable buffer or two modifiable buffers, but no other
++   combination is supported.
++
++   It is the caller's responsibility to free the malloc allocated
++   buffers by detecting that the pointers have changed from their
++   original values i.e. *ANSCP or *ANSP2 has changed.
++
++   If errors are encountered then *TERRNO is set to an appropriate
++   errno value and a zero result is returned for a recoverable error,
++   and a less-than zero result is returned for a non-recoverable error.
++
++   If no errors are encountered then *TERRNO is left unmodified and
++   a the length of the first response in bytes is returned.  */
+ static int
+ send_vc(res_state statp,
+ 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
+@@ -647,11 +737,7 @@
+ {
+ 	const HEADER *hp = (HEADER *) buf;
+ 	const HEADER *hp2 = (HEADER *) buf2;
+-	u_char *ans = *ansp;
+-	int orig_anssizp = *anssizp;
+-	// XXX REMOVE
+-	// int anssiz = *anssizp;
+-	HEADER *anhp = (HEADER *) ans;
++	HEADER *anhp = (HEADER *) *ansp;
+ 	struct sockaddr *nsap = get_nsaddr (statp, ns);
+ 	int truncating, connreset, n;
+ 	/* On some architectures compiler might emit a warning indicating
+@@ -743,6 +829,8 @@
+ 	 * Receive length & response
+ 	 */
+ 	int recvresp1 = 0;
++	/* Skip the second response if there is no second query.
++           To do that we mark the second response as received.  */
+ 	int recvresp2 = buf2 == NULL;
+ 	uint16_t rlen16;
+  read_len:
+@@ -779,40 +867,14 @@
+ 	u_char **thisansp;
+ 	int *thisresplenp;
+ 	if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
++		/* We have not received any responses
++		   yet or we only have one response to
++		   receive.  */
+ 		thisanssizp = anssizp;
+ 		thisansp = anscp ?: ansp;
+ 		assert (anscp != NULL || ansp2 == NULL);
+ 		thisresplenp = &resplen;
+ 	} else {
+-		if (*anssizp != MAXPACKET) {
+-			/* No buffer allocated for the first
+-			   reply.  We can try to use the rest
+-			   of the user-provided buffer.  */
+-#if __GNUC_PREREQ (4, 7)
+-			DIAG_PUSH_NEEDS_COMMENT;
+-			DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+-#endif
+-#if _STRING_ARCH_unaligned
+-			*anssizp2 = orig_anssizp - resplen;
+-			*ansp2 = *ansp + resplen;
+-#else
+-			int aligned_resplen
+-			  = ((resplen + __alignof__ (HEADER) - 1)
+-			     & ~(__alignof__ (HEADER) - 1));
+-			*anssizp2 = orig_anssizp - aligned_resplen;
+-			*ansp2 = *ansp + aligned_resplen;
+-#endif
+-#if __GNUC_PREREQ (4, 7)
+-			DIAG_POP_NEEDS_COMMENT;
+-#endif
+-		} else {
+-			/* The first reply did not fit into the
+-			   user-provided buffer.  Maybe the second
+-			   answer will.  */
+-			*anssizp2 = orig_anssizp;
+-			*ansp2 = *ansp;
+-		}
+-
+ 		thisanssizp = anssizp2;
+ 		thisansp = ansp2;
+ 		thisresplenp = resplen2;
+@@ -820,10 +882,14 @@
+ 	anhp = (HEADER *) *thisansp;
+ 
+ 	*thisresplenp = rlen;
+-	if (rlen > *thisanssizp) {
+-		/* Yes, we test ANSCP here.  If we have two buffers
+-		   both will be allocatable.  */
+-		if (__glibc_likely (anscp != NULL))       {
++	/* Is the answer buffer too small?  */
++	if (*thisanssizp < rlen) {
++		/* If the current buffer is non-NULL and it's not
++		   pointing at the static user-supplied buffer then
++		   we can reallocate it.  */
++		if (thisansp != NULL && thisansp != ansp) {
++			/* Always allocate MAXPACKET, callers expect
++			   this specific size.  */
+ 			u_char *newp = malloc (MAXPACKET);
+ 			if (newp == NULL) {
+ 				*terrno = ENOMEM;
+@@ -835,6 +901,9 @@
+ 			if (thisansp == ansp2)
+ 			  *ansp2_malloced = 1;
+ 			anhp = (HEADER *) newp;
++			/* A uint16_t can't be larger than MAXPACKET
++			   thus it's safe to allocate MAXPACKET but
++			   read RLEN bytes instead.  */
+ 			len = rlen;
+ 		} else {
+ 			Dprint(statp->options & RES_DEBUG,
+@@ -997,6 +1066,66 @@
+ 	return 1;
+ }
+ 
++/* The send_dg function is responsible for sending a DNS query over UDP
++   to the nameserver numbered NS from the res_state STATP i.e.
++   EXT(statp).nssocks[ns].  The function supports IPv4 and IPv6 queries
++   along with the ability to send the query in parallel for both stacks
++   (default) or serially (RES_SINGLKUP).  It also supports serial lookup
++   with a close and reopen of the socket used to talk to the server
++   (RES_SNGLKUPREOP) to work around broken name servers.
++
++   The query stored in BUF of BUFLEN length is sent first followed by
++   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
++   in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
++
++   Answers to the query are stored firstly in *ANSP up to a max of
++   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
++   is non-NULL (to indicate that modifying the answer buffer is allowed)
++   then malloc is used to allocate a new response buffer and ANSCP and
++   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
++   are needed but ANSCP is NULL, then as much of the response as
++   possible is read into the buffer, but the results will be truncated.
++   When truncation happens because of a small answer buffer the DNS
++   packets header feild TC will bet set to 1, indicating a truncated
++   message, while the rest of the UDP packet is discarded.
++
++   Answers to the query are stored secondly in *ANSP2 up to a max of
++   *ANSSIZP2 bytes, with the actual response length stored in
++   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
++   is non-NULL (required for a second query) then malloc is used to
++   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
++   size and *ANSP2_MALLOCED is set to 1.
++
++   The ANSP2_MALLOCED argument will eventually be removed as the
++   change in buffer pointer can be used to detect the buffer has
++   changed and that the caller should use free on the new buffer.
++
++   Note that the answers may arrive in any order from the server and
++   therefore the first and second answer buffers may not correspond to
++   the first and second queries.
++
++   It is not supported to call this function with a non-NULL ANSP2
++   but a NULL ANSCP.  Put another way, you can call send_vc with a
++   single unmodifiable buffer or two modifiable buffers, but no other
++   combination is supported.
++
++   It is the caller's responsibility to free the malloc allocated
++   buffers by detecting that the pointers have changed from their
++   original values i.e. *ANSCP or *ANSP2 has changed.
++
++   If an answer is truncated because of UDP datagram DNS limits then
++   *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
++   the caller to retry with TCP.  The value *GOTSOMEWHERE is set to 1
++   if any progress was made reading a response from the nameserver and
++   is used by the caller to distinguish between ECONNREFUSED and
++   ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
++
++   If errors are encountered then *TERRNO is set to an appropriate
++   errno value and a zero result is returned for a recoverable error,
++   and a less-than zero result is returned for a non-recoverable error.
++
++   If no errors are encountered then *TERRNO is left unmodified and
++   a the length of the first response in bytes is returned.  */
+ static int
+ send_dg(res_state statp,
+ 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
+@@ -1006,8 +1135,6 @@
+ {
+ 	const HEADER *hp = (HEADER *) buf;
+ 	const HEADER *hp2 = (HEADER *) buf2;
+-	u_char *ans = *ansp;
+-	int orig_anssizp = *anssizp;
+ 	struct timespec now, timeout, finish;
+ 	struct pollfd pfd[1];
+ 	int ptimeout;
+@@ -1040,6 +1167,8 @@
+ 	int need_recompute = 0;
+ 	int nwritten = 0;
+ 	int recvresp1 = 0;
++	/* Skip the second response if there is no second query.
++           To do that we mark the second response as received.  */
+ 	int recvresp2 = buf2 == NULL;
+ 	pfd[0].fd = EXT(statp).nssocks[ns];
+ 	pfd[0].events = POLLOUT;
+@@ -1203,55 +1332,56 @@
+ 		int *thisresplenp;
+ 
+ 		if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
++			/* We have not received any responses
++			   yet or we only have one response to
++			   receive.  */
+ 			thisanssizp = anssizp;
+ 			thisansp = anscp ?: ansp;
+ 			assert (anscp != NULL || ansp2 == NULL);
+ 			thisresplenp = &resplen;
+ 		} else {
+-			if (*anssizp != MAXPACKET) {
+-				/* No buffer allocated for the first
+-				   reply.  We can try to use the rest
+-				   of the user-provided buffer.  */
+-#if _STRING_ARCH_unaligned
+-				*anssizp2 = orig_anssizp - resplen;
+-				*ansp2 = *ansp + resplen;
+-#else
+-				int aligned_resplen
+-				  = ((resplen + __alignof__ (HEADER) - 1)
+-				     & ~(__alignof__ (HEADER) - 1));
+-				*anssizp2 = orig_anssizp - aligned_resplen;
+-				*ansp2 = *ansp + aligned_resplen;
+-#endif
+-			} else {
+-				/* The first reply did not fit into the
+-				   user-provided buffer.  Maybe the second
+-				   answer will.  */
+-				*anssizp2 = orig_anssizp;
+-				*ansp2 = *ansp;
+-			}
+-
+ 			thisanssizp = anssizp2;
+ 			thisansp = ansp2;
+ 			thisresplenp = resplen2;
+ 		}
+ 
+ 		if (*thisanssizp < MAXPACKET
+-		    /* Yes, we test ANSCP here.  If we have two buffers
+-		       both will be allocatable.  */
+-		    && anscp
++		    /* If the current buffer is non-NULL and it's not
++		       pointing at the static user-supplied buffer then
++		       we can reallocate it.  */
++		    && (thisansp != NULL && thisansp != ansp)
+ #ifdef FIONREAD
++		    /* Is the size too small?  */
+ 		    && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
+ 			|| *thisanssizp < *thisresplenp)
+ #endif
+                     ) {
++			/* Always allocate MAXPACKET, callers expect
++			   this specific size.  */
+ 			u_char *newp = malloc (MAXPACKET);
+ 			if (newp != NULL) {
+-				*anssizp = MAXPACKET;
+-				*thisansp = ans = newp;
++				*thisanssizp = MAXPACKET;
++				*thisansp = newp;
+ 				if (thisansp == ansp2)
+ 				  *ansp2_malloced = 1;
+ 			}
+ 		}
++		/* We could end up with truncation if anscp was NULL
++		   (not allowed to change caller's buffer) and the
++		   response buffer size is too small.  This isn't a
++		   reliable way to detect truncation because the ioctl
++		   may be an inaccurate report of the UDP message size.
++		   Therefore we use this only to issue debug output.
++		   To do truncation accurately with UDP we need
++		   MSG_TRUNC which is only available on Linux.  We
++		   can abstract out the Linux-specific feature in the
++		   future to detect truncation.  */
++		if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
++			Dprint(statp->options & RES_DEBUG,
++			       (stdout, ";; response may be truncated (UDP)\n")
++			);
++		}
++
+ 		HEADER *anhp = (HEADER *) *thisansp;
+ 		socklen_t fromlen = sizeof(struct sockaddr_in6);
+ 		assert (sizeof(from) <= fromlen);
+--- a/stdlib/cxa_thread_atexit_impl.c	2015-08-05 08:42:21.000000000 +0200
++++ b/stdlib/cxa_thread_atexit_impl.c	2016-02-16 18:13:26.990538679 +0100
+@@ -98,6 +98,10 @@
+ int
+ __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
+ {
++#ifdef PTR_MANGLE
++  PTR_MANGLE (func);
++#endif
++
+   /* Prepend.  */
+   struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
+   new->func = func;
+@@ -142,9 +146,13 @@
+   while (tls_dtor_list)
+     {
+       struct dtor_list *cur = tls_dtor_list;
++      dtor_func func = cur->func;
++#ifdef PTR_DEMANGLE
++      PTR_DEMANGLE (func);
++#endif
+ 
+       tls_dtor_list = tls_dtor_list->next;
+-      cur->func (cur->obj);
++      func (cur->obj);
+ 
+       /* Ensure that the MAP dereference happens before
+ 	 l_tls_dtor_count decrement.  That way, we protect this access from a
+--- a/string/strcoll_l.c	2015-08-05 08:42:21.000000000 +0200
++++ b/string/strcoll_l.c	2016-02-16 18:13:26.990538679 +0100
+@@ -29,7 +29,6 @@
+ # define STRING_TYPE char
+ # define USTRING_TYPE unsigned char
+ # define STRCOLL __strcoll_l
+-# define STRDIFF __strdiff
+ # define STRCMP strcmp
+ # define WEIGHT_H "../locale/weight.h"
+ # define SUFFIX	MB
+@@ -42,20 +41,6 @@
+ #include "../locale/localeinfo.h"
+ #include WEIGHT_H
+ 
+-#define MASK_UTF8_7BIT  (1 << 7)
+-#define MASK_UTF8_START (3 << 6)
+-
+-size_t
+-STRDIFF (const STRING_TYPE *s, const STRING_TYPE *t)
+-{
+-  size_t n;
+-
+-  for (n = 0; *s != '\0' && *s++ == *t++; ++n)
+-    continue;
+-
+-  return n;
+-}
+-
+ /* Track status while looking for sequences in a string.  */
+ typedef struct
+ {
+@@ -269,29 +254,9 @@
+   const USTRING_TYPE *extra;
+   const int32_t *indirect;
+ 
+-  /* In case there is no locale specific sort order (C / POSIX).  */
+   if (nrules == 0)
+     return STRCMP (s1, s2);
+ 
+-  /* Fast forward to the position of the first difference.  Needs to be
+-     encoding aware as the byte-by-byte comparison can stop in the middle
+-     of a char sequence for multibyte encodings like UTF-8.  */
+-  uint_fast32_t encoding =
+-    current->values[_NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)].word;
+-  if (encoding != __cet_other)
+-    {
+-      size_t diff = STRDIFF (s1, s2);
+-      if (diff > 0)
+-	{
+-	  if (encoding == __cet_utf8 && (*(s1 + diff) & MASK_UTF8_7BIT) != 0)
+-	    do
+-	      diff--;
+-	    while (diff > 0 && (*(s1 + diff) & MASK_UTF8_START) != MASK_UTF8_START);
+-	  s1 += diff;
+-	  s2 += diff;
+-	}
+-    }
+-
+   /* Catch empty strings.  */
+   if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0'))
+     return (*s1 != '\0') - (*s2 != '\0');
+@@ -358,8 +323,7 @@
+ 		     byte-level comparison to ensure that we don't waste time
+ 		     going through multiple passes for totally equal strings
+ 		     before proceeding to subsequent passes.  */
+-		  if (pass == 0 && encoding == __cet_other &&
+-		      STRCMP (s1, s2) == 0)
++		  if (pass == 0 && STRCMP (s1, s2) == 0)
+ 		    return result;
+ 		  else
+ 		    break;
+--- a/sysdeps/generic/ldsodefs.h	2015-08-05 08:42:21.000000000 +0200
++++ b/sysdeps/generic/ldsodefs.h	2016-02-16 18:13:26.990538679 +0100
+@@ -592,9 +592,6 @@
+   /* List of auditing interfaces.  */
+   struct audit_ifaces *_dl_audit;
+   unsigned int _dl_naudit;
+-
+-  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
+-  EXTERN int _dl_pointer_guard;
+ };
+ # define __rtld_global_attribute__
+ # if IS_IN (rtld)
+--- a/sysdeps/posix/opendir.c	2015-08-05 08:42:21.000000000 +0200
++++ b/sysdeps/posix/opendir.c	2016-02-16 18:13:26.990538679 +0100
+@@ -105,7 +105,7 @@
+     tryopen_o_directory ();
+ 
+   /* We can skip the expensive `stat' call if O_DIRECTORY works.  */
+-  return o_directory_works > 0;
++  return o_directory_works < 0;
+ #endif
+   return true;
+ }
+--- a/sysdeps/x86/fpu/bits/math-vector.h	2015-08-05 08:42:21.000000000 +0200
++++ b/sysdeps/x86/fpu/bits/math-vector.h	2016-02-16 18:13:26.991538699 +0100
+@@ -53,34 +53,5 @@
+ #  undef __DECL_SIMD_powf
+ #  define __DECL_SIMD_powf __DECL_SIMD_x86_64
+ 
+-/* Workaround to exclude unnecessary symbol aliases in libmvec
+-   while GCC creates the vector names based on scalar asm name.
+-   Corresponding discussion started at
+-   <https://gcc.gnu.org/ml/gcc/2015-06/msg00173.html>.  */
+-__asm__ ("_ZGVbN2v___log_finite = _ZGVbN2v_log");
+-__asm__ ("_ZGVcN4v___log_finite = _ZGVcN4v_log");
+-__asm__ ("_ZGVdN4v___log_finite = _ZGVdN4v_log");
+-__asm__ ("_ZGVeN8v___log_finite = _ZGVeN8v_log");
+-__asm__ ("_ZGVbN4v___logf_finite = _ZGVbN4v_logf");
+-__asm__ ("_ZGVcN8v___logf_finite = _ZGVcN8v_logf");
+-__asm__ ("_ZGVdN8v___logf_finite = _ZGVdN8v_logf");
+-__asm__ ("_ZGVeN16v___logf_finite = _ZGVeN16v_logf");
+-__asm__ ("_ZGVbN2v___exp_finite = _ZGVbN2v_exp");
+-__asm__ ("_ZGVcN4v___exp_finite = _ZGVcN4v_exp");
+-__asm__ ("_ZGVdN4v___exp_finite = _ZGVdN4v_exp");
+-__asm__ ("_ZGVeN8v___exp_finite = _ZGVeN8v_exp");
+-__asm__ ("_ZGVbN4v___expf_finite = _ZGVbN4v_expf");
+-__asm__ ("_ZGVcN8v___expf_finite = _ZGVcN8v_expf");
+-__asm__ ("_ZGVdN8v___expf_finite = _ZGVdN8v_expf");
+-__asm__ ("_ZGVeN16v___expf_finite = _ZGVeN16v_expf");
+-__asm__ ("_ZGVbN2vv___pow_finite = _ZGVbN2vv_pow");
+-__asm__ ("_ZGVcN4vv___pow_finite = _ZGVcN4vv_pow");
+-__asm__ ("_ZGVdN4vv___pow_finite = _ZGVdN4vv_pow");
+-__asm__ ("_ZGVeN8vv___pow_finite = _ZGVeN8vv_pow");
+-__asm__ ("_ZGVbN4vv___powf_finite = _ZGVbN4vv_powf");
+-__asm__ ("_ZGVcN8vv___powf_finite = _ZGVcN8vv_powf");
+-__asm__ ("_ZGVdN8vv___powf_finite = _ZGVdN8vv_powf");
+-__asm__ ("_ZGVeN16vv___powf_finite = _ZGVeN16vv_powf");
+-
+ # endif
+ #endif
+--- a/sysdeps/x86_64/fpu/Makefile	2015-08-05 08:42:21.000000000 +0200
++++ b/sysdeps/x86_64/fpu/Makefile	2016-02-16 18:13:26.991538699 +0100
+@@ -20,7 +20,10 @@
+ 		   svml_d_pow_data svml_s_powf4_core svml_s_powf8_core_avx \
+ 		   svml_s_powf8_core svml_s_powf16_core svml_s_powf_data \
+ 		   svml_s_sincosf4_core svml_s_sincosf8_core_avx \
+-		   svml_s_sincosf8_core svml_s_sincosf16_core init-arch
++		   svml_s_sincosf8_core svml_s_sincosf16_core init-arch \
++		   svml_finite_alias
++
++libmvec-static-only-routines = svml_finite_alias
+ endif
+ 
+ # Variables for libmvec tests.
+--- a/sysdeps/x86_64/fpu/svml_finite_alias.S	1970-01-01 01:00:00.000000000 +0100
++++ b/sysdeps/x86_64/fpu/svml_finite_alias.S	2016-02-16 18:13:26.991538699 +0100
+@@ -0,0 +1,59 @@
++/* These aliases added as workaround to exclude unnecessary symbol
++   aliases in libmvec.so while compiler creates the vector names
++   based on scalar asm name.  Corresponding discussion is at
++   <https://gcc.gnu.org/ml/gcc/2015-06/msg00173.html>.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++#define ALIAS_IMPL(alias, target) \
++ENTRY (alias); \
++	call target; \
++	ret; \
++END (alias)
++
++	.text
++ALIAS_IMPL (_ZGVbN2v___log_finite, _ZGVbN2v_log)
++ALIAS_IMPL (_ZGVcN4v___log_finite, _ZGVcN4v_log)
++ALIAS_IMPL (_ZGVdN4v___log_finite, _ZGVdN4v_log)
++ALIAS_IMPL (_ZGVeN8v___log_finite, _ZGVeN8v_log)
++
++ALIAS_IMPL (_ZGVbN4v___logf_finite, _ZGVbN4v_logf)
++ALIAS_IMPL (_ZGVcN8v___logf_finite, _ZGVcN8v_logf)
++ALIAS_IMPL (_ZGVdN8v___logf_finite, _ZGVdN8v_logf)
++ALIAS_IMPL (_ZGVeN16v___logf_finite, _ZGVeN16v_logf)
++
++ALIAS_IMPL (_ZGVbN2v___exp_finite, _ZGVbN2v_exp)
++ALIAS_IMPL (_ZGVcN4v___exp_finite, _ZGVcN4v_exp)
++ALIAS_IMPL (_ZGVdN4v___exp_finite, _ZGVdN4v_exp)
++ALIAS_IMPL (_ZGVeN8v___exp_finite, _ZGVeN8v_exp)
++
++ALIAS_IMPL (_ZGVbN4v___expf_finite, _ZGVbN4v_expf)
++ALIAS_IMPL (_ZGVcN8v___expf_finite, _ZGVcN8v_expf)
++ALIAS_IMPL (_ZGVdN8v___expf_finite, _ZGVdN8v_expf)
++ALIAS_IMPL (_ZGVeN16v___expf_finite, _ZGVeN16v_expf)
++
++ALIAS_IMPL (_ZGVbN2vv___pow_finite, _ZGVbN2vv_pow)
++ALIAS_IMPL (_ZGVcN4vv___pow_finite, _ZGVcN4vv_pow)
++ALIAS_IMPL (_ZGVdN4vv___pow_finite, _ZGVdN4vv_pow)
++ALIAS_IMPL (_ZGVeN8vv___pow_finite, _ZGVeN8vv_pow)
++
++ALIAS_IMPL (_ZGVbN4vv___powf_finite, _ZGVbN4vv_powf)
++ALIAS_IMPL (_ZGVcN8vv___powf_finite, _ZGVcN8vv_powf)
++ALIAS_IMPL (_ZGVdN8vv___powf_finite, _ZGVdN8vv_powf)
++ALIAS_IMPL (_ZGVeN16vv___powf_finite, _ZGVeN16vv_powf)
+--- a/time/strftime_l.c	2015-08-05 08:42:21.000000000 +0200
++++ b/time/strftime_l.c	2016-02-16 18:13:26.991538699 +0100
+@@ -510,13 +510,17 @@
+      only a few elements.  Dereference the pointers only if the format
+      requires this.  Then it is ok to fail if the pointers are invalid.  */
+ # define a_wkday \
+-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
++  ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6			     \
++		     ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
+ # define f_wkday \
+-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
++  ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6			     \
++		     ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
+ # define a_month \
+-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
++  ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11			     \
++		     ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
+ # define f_month \
+-  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
++  ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11			     \
++		     ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
+ # define ampm \
+   ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11		      \
+ 				 ? NLW(PM_STR) : NLW(AM_STR)))
+@@ -526,8 +530,10 @@
+ # define ap_len STRLEN (ampm)
+ #else
+ # if !HAVE_STRFTIME
+-#  define f_wkday (weekday_name[tp->tm_wday])
+-#  define f_month (month_name[tp->tm_mon])
++#  define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6	\
++		   ? "?" : weekday_name[tp->tm_wday])
++#  define f_month (tp->tm_mon < 0 || tp->tm_mon > 11	\
++		   ? "?" : month_name[tp->tm_mon])
+ #  define a_wkday f_wkday
+ #  define a_month f_month
+ #  define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
+@@ -1321,7 +1327,7 @@
+ 		  *tzset_called = true;
+ 		}
+ # endif
+-	      zone = tzname[tp->tm_isdst];
++	      zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
+ 	    }
+ #endif
+ 	  if (! zone)
+--- a/wcsmbs/wcscoll_l.c	2015-08-05 08:42:21.000000000 +0200
++++ b/wcsmbs/wcscoll_l.c	2016-02-16 18:13:26.991538699 +0100
+@@ -23,7 +23,6 @@
+ #define STRING_TYPE wchar_t
+ #define USTRING_TYPE wint_t
+ #define STRCOLL __wcscoll_l
+-#define STRDIFF __wcsdiff
+ #define STRCMP __wcscmp
+ #define WEIGHT_H "../locale/weightwc.h"
+ #define SUFFIX	WC

Added: trunk/mpfr/mpfr-3.1.3-upstream_fixes-2.patch
==============================================================================
Binary file. No diff available.


More information about the patches mailing list