diff mbox

gcc-4_9-branch backports

Message ID 20160211094908.GA3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 11, 2016, 9:49 a.m. UTC
Hi!

I've committed following backports of my trunk commits to gcc-4_9-branch
after bootstrapping/regtesting them on x86_64-linux and i686-linux.

	Jakub
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-11-19  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/60736
	* include/cpplib.h (cpp_errno_filename): New prototype.
	* errors.c (cpp_errno): Don't handle msgid "" specially, use
	_(msgid) instead of msgid as argument to cpp_error.
	(cpp_errno_filename): New function.
	* files.c (read_file_guts): Use cpp_errno_filename instead of
	cpp_errno.
	(open_file_failed): Likewise.  Use file->name if file->path is NULL
	in diagnostics.
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-11-19  Jakub Jelinek  <jakub@redhat.com>

	PR target/67770
	* config/i386/i386.md (simple_return): Disable if
	ix86_static_chain_on_stack is true.

	* gcc.target/i386/pr67770.c: New test.

--- gcc/config/i386/i386.md	(revision 230592)
+++ gcc/config/i386/i386.md	(revision 230593)
@@ -12203,10 +12203,14 @@ (define_expand "return"
 ;; We need to disable this for TARGET_SEH, as otherwise
 ;; shrink-wrapped prologue gets enabled too.  This might exceed
 ;; the maximum size of prologue in unwind information.
+;; Also disallow shrink-wrapping if using stack slot to pass the
+;; static chain pointer - the first instruction has to be pushl %esi
+;; and it can't be moved around, as we use alternate entry points
+;; in that case.
 
 (define_expand "simple_return"
   [(simple_return)]
-  "!TARGET_SEH"
+  "!TARGET_SEH && !ix86_static_chain_on_stack"
 {
   if (crtl->args.pops_args)
     {
--- gcc/testsuite/gcc.target/i386/pr67770.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr67770.c	(revision 230593)
@@ -0,0 +1,40 @@
+/* PR target/67770 */
+/* { dg-do run { target ia32 } } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-O2" } */
+
+#ifndef NO_TRAMPOLINES
+__attribute__ ((noinline)) void
+foo (int i, void (* __attribute__ ((regparm (3))) bar) (int))
+{
+  bar (i);
+}
+#endif
+
+int
+main ()
+{
+#ifndef NO_TRAMPOLINES
+  int p = 0;
+
+  __attribute__ ((regparm (3), noinline)) void
+  bar (int i)
+  {
+    if (__builtin_expect (i, 0))
+      ++p;
+  }
+
+  foo (0, bar);
+  bar (0);
+
+  if (p != 0)
+    __builtin_abort ();
+
+  foo (1, bar);
+  bar (1);
+
+  if (p != 2)
+    __builtin_abort ();
+#endif
+  return 0;
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-11-21  Jakub Jelinek  <jakub@redhat.com>

	PR debug/66432
	* tree-inline.c (copy_debug_stmt): If
	gimple_debug_source_bind_get_value is DECL_ORIGIN of a PARM_DECL
	in decl_debug_args, don't call remap_gimple_op_r on it.

	* gcc.dg/debug/pr66432.c: New test.

--- gcc/tree-inline.c	(revision 230701)
+++ gcc/tree-inline.c	(revision 230702)
@@ -2864,8 +2864,6 @@ copy_debug_stmt (gdebug *stmt, copy_body
   else if (gimple_debug_source_bind_p (stmt))
     {
       gimple_debug_source_bind_set_var (stmt, t);
-      walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
-		 remap_gimple_op_r, &wi, NULL);
       /* When inlining and source bind refers to one of the optimized
 	 away parameters, change the source bind into normal debug bind
 	 referring to the corresponding DEBUG_EXPR_DECL that should have
@@ -2889,7 +2887,10 @@ copy_debug_stmt (gdebug *stmt, copy_body
 		    break;
 		  }
 	    }
-	}      
+	}
+      if (gimple_debug_source_bind_p (stmt))
+	walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
+		   remap_gimple_op_r, &wi, NULL);
     }
 
   processing_debug_stmt = 0;
--- gcc/testsuite/gcc.dg/debug/pr66432.c	(revision 0)
+++ gcc/testsuite/gcc.dg/debug/pr66432.c	(revision 230702)
@@ -0,0 +1,19 @@
+/* PR debug/66432 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+extern void baz (const char *, const char *) __attribute__ ((__noreturn__));
+
+void
+foo (int x, int y[x][x])
+{
+  if (x < 2)
+    baz ("", "");
+}
+
+void
+bar (void)
+{
+  int z[2][2] = { { 1, 2 }, { 3, 4 } };
+  foo (2, z);
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-12-03  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/57580
	* c-ppoutput.c (print): Change printed field to bool.
	(init_pp_output): Set print.printed to false instead of 0.
	(scan_translation_unit): Fix up formatting.  Set print.printed
	to true after printing something other than newline.
	(scan_translation_unit_trad): Set print.printed to true instead of 1.
	(maybe_print_line_1): Set print.printed to false instead of 0.
	(print_line_1): Likewise.
	(do_line_change): Set print.printed to true instead of 1.
	(cb_define, dump_queued_macros, cb_include, cb_def_pragma,
	dump_macro): Set print.printed to false after printing newline.

	* c-c++-common/cpp/pr57580.c: New test.
	* c-c++-common/gomp/pr57580.c: New test.

--- gcc/c-family/c-ppoutput.c	(revision 231212)
+++ gcc/c-family/c-ppoutput.c	(revision 231213)
@@ -33,7 +33,7 @@ static struct
   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.  */
 } print;
@@ -151,7 +151,7 @@ init_pp_output (FILE *out_stream)
 
   /* 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;
@@ -202,12 +202,16 @@ scan_translation_unit (cpp_reader *pfile
 	    {
 	      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)
 	{
@@ -218,6 +222,7 @@ scan_translation_unit (cpp_reader *pfile
 	      && !in_pragma)
 	    do_line_change (pfile, token, loc, false);
 	  putc (' ', print.outf);
+	  print.printed = true;
 	}
 
       avoid_paste = false;
@@ -235,7 +240,7 @@ scan_translation_unit (cpp_reader *pfile
 	    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)
@@ -246,9 +251,9 @@ scan_translation_unit (cpp_reader *pfile
       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);
 	  cpp_output_token (token, print.outf);
+	  print.printed = true;
 	}
 
       /* CPP_COMMENT tokens and raw-string literal tokens can
@@ -298,7 +303,7 @@ scan_translation_unit_trad (cpp_reader *
       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);
     }
@@ -319,7 +324,7 @@ maybe_print_line_1 (source_location src_
     {
       putc ('\n', stream);
       print.src_line++;
-      print.printed = 0;
+      print.printed = false;
     }
 
   if (!flag_no_line_commands
@@ -360,7 +365,7 @@ print_line_1 (source_location src_loc, c
   /* End any previous line of text.  */
   if (print.printed)
     putc ('\n', stream);
-  print.printed = 0;
+  print.printed = false;
 
   if (!flag_no_line_commands)
     {
@@ -429,7 +434,7 @@ do_line_change (cpp_reader *pfile, const
   if (!CPP_OPTION (pfile, traditional))
     {
       int spaces = LOCATION_COLUMN (src_loc) - 2;
-      print.printed = 1;
+      print.printed = true;
 
       while (-- spaces >= 0)
 	putc (' ', print.outf);
@@ -470,6 +475,7 @@ cb_define (cpp_reader *pfile, source_loc
     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);
@@ -521,7 +527,7 @@ dump_queued_macros (cpp_reader *pfile AT
     {
       putc ('\n', print.outf);
       print.src_line++;
-      print.printed = 0;
+      print.printed = false;
     }
 
   for (q = define_queue; q;)
@@ -530,6 +536,7 @@ dump_queued_macros (cpp_reader *pfile AT
       fputs ("#define ", print.outf);
       fputs (q->macro, print.outf);
       putc ('\n', print.outf);
+      print.printed = false;
       print.src_line++;
       oq = q;
       q = q->next;
@@ -573,6 +580,7 @@ cb_include (cpp_reader *pfile ATTRIBUTE_
     }
 
   putc ('\n', print.outf);
+  print.printed = false;
   print.src_line++;
 }
 
@@ -638,6 +646,7 @@ cb_def_pragma (cpp_reader *pfile, source
   maybe_print_line (line);
   fputs ("#pragma ", print.outf);
   cpp_output_line (pfile, print.outf);
+  print.printed = false;
   print.src_line++;
 }
 
@@ -651,6 +660,7 @@ dump_macro (cpp_reader *pfile, cpp_hashn
       fputs ((const char *) cpp_macro_definition (pfile, node),
 	     print.outf);
       putc ('\n', print.outf);
+      print.printed = false;
       print.src_line++;
     }
 
--- gcc/testsuite/c-c++-common/cpp/pr57580.c	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr57580.c	(revision 231213)
@@ -0,0 +1,9 @@
+/* PR preprocessor/57580 */
+/* { dg-do compile } */
+/* { dg-options "-save-temps" } */
+
+#define MSG 	\
+  _Pragma("message(\"message0\")")	\
+  _Pragma("message(\"message1\")")
+MSG	/* { dg-message "message0" } */
+/* { dg-message "message1" "" { target *-*-* } 8 } */
--- gcc/testsuite/c-c++-common/gomp/pr57580.c	(revision 0)
+++ gcc/testsuite/c-c++-common/gomp/pr57580.c	(revision 231213)
@@ -0,0 +1,36 @@
+/* PR preprocessor/57580 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -save-temps -fdump-tree-gimple" } */
+
+#define PS \
+  _Pragma("omp parallel num_threads(2)") \
+  { \
+    _Pragma("omp single") \
+    { \
+      ret = 0; \
+    } \
+  }
+
+int
+main ()
+{
+  int ret;
+  _Pragma("omp parallel num_threads(3)")
+  {
+    _Pragma("omp single")
+    {
+      ret = 0;
+    }
+  }
+  _Pragma("omp parallel num_threads(4)") { _Pragma("omp single") { ret = 0; } }
+  { _Pragma("omp parallel num_threads(5)") { _Pragma("omp single") { ret = 0; } } }
+  PS
+  PS
+  return ret;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(2\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(3\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(4\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(5\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp single" 5 "gimple" } } */
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-12-04  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/68680
	* calls.c (special_function_p): Return ECF_MAY_BE_ALLOCA for
	BUILT_IN_ALLOCA{,_WITH_ALIGN}.  Don't check for __builtin_alloca
	by name.

	* gcc.target/i386/pr68680.c: New test.

--- gcc/calls.c	(revision 231278)
+++ gcc/calls.c	(revision 231279)
@@ -521,12 +521,9 @@ special_function_p (const_tree fndecl, i
       /* 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 (DECL_NAME (fndecl)) == 6
-	    && name[0] == 'a'
-	    && ! strcmp (name, "alloca"))
-	   || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
-	       && name[0] == '_'
-	       && ! strcmp (name, "__builtin_alloca"))))
+      if (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
+	  && name[0] == 'a'
+	  && ! strcmp (name, "alloca"))
 	flags |= ECF_MAY_BE_ALLOCA;
 
       /* Disregard prefix _, __, __x or __builtin_.  */
@@ -572,6 +569,17 @@ special_function_p (const_tree fndecl, i
 	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;
 }
 
--- gcc/testsuite/gcc.target/i386/pr68680.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr68680.c	(revision 231279)
@@ -0,0 +1,15 @@
+/* PR tree-optimization/68680 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-protector-strong" } */
+
+int foo (char *);
+
+int
+bar (unsigned long x)
+{
+  char a[x];
+  return foo (a);
+}
+
+/* Verify that this function is stack protected.  */
+/* { dg-final { scan-assembler "stack_chk_fail" } } */
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-12-10  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/68376
	PR rtl-optimization/68670
	* ifcvt.c (noce_try_abs): For one_cmpl allow < 0, >= 0
	or > -1 conditions regardless of negate, and disallow
	all other conditions.

	* gcc.c-torture/execute/pr68376-2.c (f5, f6, f7, f8): New
	tests.
	(main): Call them.
	* gcc.dg/pr68670-1.c: New test.
	* gcc.dg/pr68670-2.c: New test.

	2015-11-19  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/68376
	* ifcvt.c (noce_try_abs): Disable one_cmpl optimization if
	encountering x <= 0 ? ~x : x or x > 0 ? ~x : x.

	* gcc.c-torture/execute/pr68376-1.c: New test.
	* gcc.c-torture/execute/pr68376-2.c: New test.

--- gcc/ifcvt.c	(revision 230595)
+++ gcc/ifcvt.c	(revision 231526)
@@ -2071,12 +2071,26 @@ noce_try_abs (struct noce_if_info *if_in
 
   /* Work around funny ideas get_condition has wrt canonicalization.
      Note that these rtx constants are known to be CONST_INT, and
-     therefore imply integer comparisons.  */
+     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 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)
     ;
   else if (c == const1_rtx && GET_CODE (cond) == LT)
-    ;
-  else if (c != CONST0_RTX (GET_MODE (b)))
+    {
+      if (one_cmpl)
+	return FALSE;
+    }
+  else if (c == CONST0_RTX (GET_MODE (b)))
+    {
+      if (one_cmpl
+	  && GET_CODE (cond) != GE
+	  && GET_CODE (cond) != LT)
+	return FALSE;
+    }
+  else
     return FALSE;
 
   /* Determine what sort of operation this is.  */
--- gcc/testsuite/gcc.c-torture/execute/pr68376-1.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr68376-1.c	(revision 230596)
@@ -0,0 +1,24 @@
+/* PR rtl-optimization/68376 */
+
+int a, b, c = 1;
+signed char d;
+
+int
+main ()
+{
+  for (; a < 1; a++)
+    for (; b < 1; b++)
+      {
+	signed char e = ~d;
+	if (d < 1)
+	  e = d;
+	d = e;
+	if (!c)
+	  __builtin_abort ();
+      }
+
+  if (d != 0)
+    __builtin_abort ();
+
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr68376-2.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr68376-2.c	(revision 231526)
@@ -0,0 +1,73 @@
+/* PR rtl-optimization/68376 */
+
+extern void abort (void);
+
+__attribute__((noinline, noclone)) int
+f1 (int x)
+{
+  return x < 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f2 (int x)
+{
+  return x < 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f3 (int x)
+{
+  return x <= 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f4 (int x)
+{
+  return x <= 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f5 (int x)
+{
+  return x >= 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f6 (int x)
+{
+  return x >= 0 ? x : ~x;
+}
+
+__attribute__((noinline, noclone)) int
+f7 (int x)
+{
+  return x > 0 ? ~x : x;
+}
+
+__attribute__((noinline, noclone)) int
+f8 (int x)
+{
+  return x > 0 ? x : ~x;
+}
+
+int
+main ()
+{
+  if (f1 (5) != 5 || f1 (-5) != 4 || f1 (0) != 0)
+    abort ();
+  if (f2 (5) != -6 || f2 (-5) != -5 || f2 (0) != -1)
+    abort ();
+  if (f3 (5) != 5 || f3 (-5) != 4 || f3 (0) != -1)
+    abort ();
+  if (f4 (5) != -6 || f4 (-5) != -5 || f4 (0) != 0)
+    abort ();
+  if (f5 (5) != -6 || f5 (-5) != -5 || f5 (0) != -1)
+    abort ();
+  if (f6 (5) != 5 || f6 (-5) != 4 || f6 (0) != 0)
+    abort ();
+  if (f7 (5) != -6 || f7 (-5) != -5 || f7 (0) != 0)
+    abort ();
+  if (f8 (5) != 5 || f8 (-5) != 4 || f8 (0) != -1)
+    abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.dg/pr68670-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr68670-1.c	(revision 231526)
@@ -0,0 +1,5 @@
+/* PR rtl-optimization/68670 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftracer" } */
+
+#include "../gcc.c-torture/execute/pr68376-1.c"
--- gcc/testsuite/gcc.dg/pr68670-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr68670-2.c	(revision 231526)
@@ -0,0 +1,5 @@
+/* PR rtl-optimization/68670 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftracer" } */
+
+#include "../gcc.c-torture/execute/pr68376-2.c"
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-01  Jakub Jelinek  <jakub@redhat.com>

	PR target/69015
	* ifcvt.c (find_cond_trap): Give up if returnjump_p (jump).

	* gcc.dg/pr69015.c: New test.

--- gcc/ifcvt.c	(revision 232019)
+++ gcc/ifcvt.c	(revision 232020)
@@ -4526,8 +4526,11 @@ find_cond_trap (basic_block test_bb, edg
     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.  */
--- gcc/testsuite/gcc.dg/pr69015.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr69015.c	(revision 232020)
@@ -0,0 +1,10 @@
+/* PR target/69015 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-if-conversion" } */
+
+void
+foo (int c)
+{
+  if (c)
+    __builtin_trap ();
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-07  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/68960
	* gimple-expr.c (copy_var_decl): If var has DECL_USER_ALIGN set, copy
	it and DECL_ALIGN too.

	* testsuite/libgomp.c/pr68960.c: New test.

--- gcc/gimple-expr.c	(revision 232121)
+++ gcc/gimple-expr.c	(revision 232122)
@@ -375,6 +375,11 @@ copy_var_decl (tree var, tree name, tree
   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;
 }
--- libgomp/testsuite/libgomp.c/pr68960.c	(revision 0)
+++ libgomp/testsuite/libgomp.c/pr68960.c	(revision 232122)
@@ -0,0 +1,25 @@
+/* PR middle-end/68960 */
+/* { dg-do run } */
+
+int
+main ()
+{
+  int temp[257] __attribute__ ((aligned (256))) = { 0 };
+  #pragma omp parallel private (temp) num_threads (2)
+  {
+    int *p = &temp[0];
+    asm volatile ("" : "+g" (p));
+    if (((__UINTPTR_TYPE__) p) & 255)
+      __builtin_abort ();
+  }
+  #pragma omp parallel num_threads (2)
+  #pragma omp single
+  #pragma omp task firstprivate (temp)
+  {
+    int *p = &temp[0];
+    asm volatile ("" : "+g" (p));
+    if (((__UINTPTR_TYPE__) p) & 255)
+      __builtin_abort ();
+  }
+  return 0;
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/69128
	* trans.h (OMPWS_SCALARIZER_BODY): Define.
	(OMPWS_NOWAIT): Renumber.
	* trans-stmt.c (gfc_trans_where_3): Only set OMPWS_SCALARIZER_WS
	if OMPWS_SCALARIZER_BODY is not set already, and set also
	OMPWS_SCALARIZER_BODY until the final loop creation.
	* trans-expr.c (gfc_trans_assignment_1): Likewise.
	* trans-openmp.c (gfc_trans_omp_workshare): Also clear
	OMPWS_SCALARIZER_BODY.
	* trans-array.c (gfc_trans_scalarized_loop_end): Don't create
	OMP_FOR if OMPWS_SCALARIZER_BODY is set.

	* gfortran.dg/gomp/pr69128.f90: New test.

--- gcc/fortran/trans.h	(revision 232150)
+++ gcc/fortran/trans.h	(revision 232151)
@@ -1039,7 +1039,9 @@ extern const char gfc_msg_wrong_return[]
 					   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 */
--- gcc/fortran/trans-stmt.c	(revision 232150)
+++ gcc/fortran/trans-stmt.c	(revision 232151)
@@ -5057,10 +5057,15 @@ gfc_trans_where_3 (gfc_code * cblock, gf
   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;
@@ -5160,6 +5165,8 @@ gfc_trans_where_3 (gfc_code * cblock, gf
   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);
--- gcc/fortran/trans-expr.c	(revision 232150)
+++ gcc/fortran/trans-expr.c	(revision 232151)
@@ -9160,6 +9160,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1
   bool scalar_to_array;
   tree string_length;
   int n;
+  bool maybe_workshare = false;
 
   /* Assignment of the form lhs = rhs.  */
   gfc_start_block (&block);
@@ -9234,8 +9235,13 @@ gfc_trans_assignment_1 (gfc_expr * expr1
 	}
 
       /* 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);
@@ -9384,6 +9390,9 @@ gfc_trans_assignment_1 (gfc_expr * expr1
 	    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);
 
--- gcc/fortran/trans-openmp.c	(revision 232150)
+++ gcc/fortran/trans-openmp.c	(revision 232151)
@@ -4297,7 +4297,7 @@ gfc_trans_omp_workshare (gfc_code *code,
 
       /* 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)
 	{
--- gcc/fortran/trans-array.c	(revision 232150)
+++ gcc/fortran/trans-array.c	(revision 232151)
@@ -3601,7 +3601,8 @@ gfc_trans_scalarized_loop_end (gfc_loopi
   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)
     {
--- gcc/testsuite/gfortran.dg/gomp/pr69128.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/gomp/pr69128.f90	(revision 232151)
@@ -0,0 +1,23 @@
+! PR fortran/69128
+! { dg-do compile }
+
+program test
+  implicit none
+  interface
+    subroutine use(b, c)
+      real, allocatable :: b(:), c(:)
+    end subroutine
+  end interface
+  real, allocatable :: a(:,:), b(:), c(:)
+  integer :: dim1, dim2, i,j
+  dim1=10000
+  dim2=500
+  allocate(a(dim1,dim2),b(dim1),c(dim1))
+  call random_number(a)
+
+!$omp parallel workshare
+  b(:) = maxval(a(:,:), dim=2)
+  c(:) = sum(a(:,:), dim=2)
+!$omp end parallel workshare
+  call use(b, c)
+end program
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-11  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/69214
	* tree-vrp.c (simplify_cond_using_ranges): Don't propagate
	innerop into a comparison if SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
	Formatting fix.

	* gcc.c-torture/compile/pr69214.c: New test.

--- gcc/tree-vrp.c	(revision 232234)
+++ gcc/tree-vrp.c	(revision 232235)
@@ -9534,7 +9534,8 @@ simplify_cond_using_ranges (gcond *stmt)
       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 @@ simplify_cond_using_ranges (gcond *stmt)
 		  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);
--- gcc/testsuite/gcc.c-torture/compile/pr69214.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr69214.c	(revision 232235)
@@ -0,0 +1,17 @@
+/* PR tree-optimization/69214 */
+
+extern void bar (void);
+extern int __setjmp (char *);
+
+void
+foo (char *p)
+{
+  int d = 0;
+  bar ();
+  if (__setjmp (p))
+    return;
+  long a = d;
+  d = 8;
+  if (!a)
+    bar ();
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-19  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/68955
	PR rtl-optimization/64557
	* dse.c (record_store, check_mem_read_rtx): Don't call get_addr
	here.  Fix up formatting.
	* alias.c (get_addr): Handle VALUE +/- CONST_SCALAR_INT_P.

	* gcc.dg/torture/pr68955.c: New test.

--- gcc/dse.c	(revision 232553)
+++ gcc/dse.c	(revision 232554)
@@ -1571,14 +1571,9 @@ record_store (rtx body, bb_info_t bb_inf
 	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 @@ check_mem_read_rtx (rtx *loc, bb_info_t
 	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);
     }
--- gcc/alias.c	(revision 232553)
+++ gcc/alias.c	(revision 232554)
@@ -2193,8 +2193,8 @@ refs_newer_value_p (const_rtx expr, rtx
 }
 
 /* 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)
@@ -2203,7 +2203,23 @@ get_addr (rtx x)
   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)
     {
--- gcc/testsuite/gcc.dg/torture/pr68955.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr68955.c	(revision 232554)
@@ -0,0 +1,41 @@
+/* PR rtl-optimization/68955 */
+/* { dg-do run } */
+/* { dg-output "ONE1ONE" } */
+
+int a, b, c, d, g, m;
+int i[7][7][5] = { { { 5 } }, { { 5 } },
+		   { { 5 }, { 5 }, { 5 }, { 5 }, { 5 }, { -1 } } };
+static int j = 11;
+short e, f, h, k, l;
+
+static void
+foo ()
+{
+  for (; e < 5; e++)
+    for (h = 3; h; h--)
+      {
+	for (g = 1; g < 6; g++)
+	  {
+	    m = c == 0 ? b : b / c;
+	    i[e][1][e] = i[1][1][1] | (m & l) && f;
+	  }
+	for (k = 0; k < 6; k++)
+	  {
+	    for (d = 0; d < 6; d++)
+	      i[1][e][h] = i[h][k][e] >= l;
+	    i[e + 2][h + 3][e] = 6 & l;
+	    i[2][1][2] = a;
+	    for (; j < 5;)
+	      for (;;)
+		;
+	  }
+      }
+}
+
+int
+main ()
+{
+  foo ();
+  __builtin_printf ("ONE%dONE\n", i[1][0][2]);
+  return 0;
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-21  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/67653
	* gimplify.c (gimplify_asm_expr): Warn if it is too late to
	attempt to mark memory input operand addressable and
	call prepare_gimple_addressable in that case.  Don't adjust
	input_location for diagnostics, use error_at instead.

	* c-c++-common/pr67653.c: New test.
	* gcc.dg/torture/pr29119.c: Add dg-warning.

--- gcc/gimplify.c	(revision 232639)
+++ gcc/gimplify.c	(revision 232640)
@@ -5305,12 +5305,38 @@ gimplify_asm_expr (tree *expr_p, gimple_
 	    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;
 	    }
 	}
--- gcc/testsuite/gcc.dg/torture/pr29119.c	(revision 232639)
+++ gcc/testsuite/gcc.dg/torture/pr29119.c	(revision 232640)
@@ -2,6 +2,5 @@
 
 void ldt_add_entry(void)
 {
-   __asm__ ("" :: "m"(({unsigned __v; __v;})));
+   __asm__ ("" :: "m"(({unsigned __v; __v;})));	/* { dg-warning "memory input 0 is not directly addressable" } */
 }
-
--- gcc/testsuite/c-c++-common/pr67653.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr67653.c	(revision 232640)
@@ -0,0 +1,8 @@
+/* PR middle-end/67653 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  __asm__ ("" : : "m" (({ static int a; a; })));	/* { dg-warning "memory input 0 is not directly addressable" } */
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/69432
	* config/i386/i386.c (expand_small_movmem_or_setmem,
	expand_set_or_movmem_prologue_epilogue_by_misaligned_moves): Spelling
	fixes.
	(ix86_expand_set_or_movmem): Call do_pending_stack_adjust () early
	if dynamic_check != -1.

	* g++.dg/opt/pr69432.C: New test.

--- gcc/config/i386/i386.c	(revision 232753)
+++ gcc/config/i386/i386.c	(revision 232754)
@@ -24376,7 +24377,7 @@ expand_small_movmem_or_setmem (rtx destm
        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:
@@ -24550,8 +24551,8 @@ expand_set_or_movmem_prologue_epilogue_b
       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);
@@ -25129,6 +25130,13 @@ ix86_expand_set_or_movmem (rtx dst, rtx
   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;
--- gcc/testsuite/g++.dg/opt/pr69432.C	(revision 0)
+++ gcc/testsuite/g++.dg/opt/pr69432.C	(revision 232754)
@@ -0,0 +1,62 @@
+// PR target/69432
+// { dg-do compile }
+// { dg-options "-O3" }
+// { dg-additional-options "-minline-stringops-dynamically" { target i?86-*-* x86_64-*-* } }
+
+template <typename S, typename T, typename U>
+void
+f1 (S x, T y, U z)
+{
+  for (; y; --y, ++x)
+    *x = z;
+}
+
+template <typename S, typename T, typename U>
+void f2 (S x, T y, U z)
+{
+  f1 (x, y, z);
+}
+
+struct A {};
+struct B { static char f3 (A, unsigned); };
+
+template <typename S, typename U>
+void f4 (S, U);
+
+struct C
+{
+  template <typename S, typename T, typename U>
+  static S f5 (S x, T y, U z) { f2 (x, y, z); }
+};
+
+template <typename S, typename T, typename U>
+void f6 (S x, T y, U z) { C::f5 (x, y, z); }
+
+template <typename S, typename T, typename U, typename V>
+void f7 (S x, T y, U z, V) { f6 (x, y, z); }
+
+struct E
+{
+  struct D : A { char e; D (A); };
+  A f;
+  E (int x) : g(f) { f8 (x); }
+  ~E ();
+  D g;
+  void f9 (int x) { x ? B::f3 (g, x) : char (); }
+  void f8 (int x) { f9 (x); }
+};
+
+struct F : E
+{
+  F (int x) : E(x) { f10 (x); f4 (this, 0); }
+  char h;
+  void f10 (int x) { f7 (&g.e, x, h, 0); }
+};
+
+long a;
+
+void
+test ()
+{
+  F b(a);
+}
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-28  Jakub Jelinek  <jakub@redhat.com>

	PR pch/68176
	* files.c (_cpp_find_file): Set file->implicit_preinclude even if
	included from file->implicit_preinclude header.

--- libcpp/files.c	(revision 232955)
+++ libcpp/files.c	(revision 232956)
@@ -522,7 +522,10 @@ _cpp_find_file (cpp_reader *pfile, const
     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 ;)
2016-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-02-08  Jakub Jelinek  <jakub@redhat.com>

	PR c++/59627
	* parser.c (cp_parser_omp_declare_reduction): Set assembler name
	of the DECL_OMP_DECLARE_REDUCTION_P decls.

	* g++.dg/gomp/pr59627.C: New test.

--- gcc/cp/parser.c	(revision 233224)
+++ gcc/cp/parser.c	(revision 233225)
@@ -36080,6 +36080,7 @@ cp_parser_omp_declare_reduction (cp_pars
       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));
--- gcc/testsuite/g++.dg/gomp/pr59627.C	(revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr59627.C	(revision 233225)
@@ -0,0 +1,14 @@
+// PR c++/59627
+// { dg-do compile { target lto } }
+// { dg-options "-fopenmp -flto" }
+
+struct A { A () : i (0) {} int i; };
+
+void
+foo ()
+{
+  A a;
+  #pragma omp declare reduction (+: A: omp_out.i += omp_in.i)
+  #pragma omp parallel reduction (+: a)
+  ;
+}
diff mbox

Patch

--- libcpp/include/cpplib.h	(revision 230590)
+++ libcpp/include/cpplib.h	(revision 230591)
@@ -986,6 +986,9 @@  extern bool cpp_warning_syshdr (cpp_read
 /* Output a diagnostic with "MSGID: " preceding the
    error string of errno.  No location is printed.  */
 extern bool cpp_errno (cpp_reader *, int, const char *msgid);
+/* Similarly, but with "FILENAME: " instead of "MSGID: ", where
+   the filename is not localized.  */
+extern bool cpp_errno_filename (cpp_reader *, int, const char *filename);
 
 /* Same as cpp_error, except additionally specifies a position as a
    (translation unit) physical line and physical column.  If the line is
--- libcpp/files.c	(revision 230590)
+++ libcpp/files.c	(revision 230591)
@@ -715,7 +715,7 @@  read_file_guts (cpp_reader *pfile, _cpp_
 
   if (count < 0)
     {
-      cpp_errno (pfile, CPP_DL_ERROR, file->path);
+      cpp_errno_filename (pfile, CPP_DL_ERROR, file->path);
       free (buf);
       return false;
     }
@@ -1053,7 +1053,8 @@  open_file_failed (cpp_reader *pfile, _cp
       /* If the preprocessor output (other than dependency information) is
          being used, we must also flag an error.  */
       if (CPP_OPTION (pfile, deps.need_preprocessor_output))
-	cpp_errno (pfile, CPP_DL_FATAL, file->path);
+	cpp_errno_filename (pfile, CPP_DL_FATAL,
+			    file->path ? file->path : file->name);
     }
   else
     {
@@ -1067,9 +1068,11 @@  open_file_failed (cpp_reader *pfile, _cp
       if (CPP_OPTION (pfile, deps.style) == DEPS_NONE
           || print_dep
           || CPP_OPTION (pfile, deps.need_preprocessor_output))
-	cpp_errno (pfile, CPP_DL_FATAL, file->path);
+	cpp_errno_filename (pfile, CPP_DL_FATAL,
+			    file->path ? file->path : file->name);
       else
-	cpp_errno (pfile, CPP_DL_WARNING, file->path);
+	cpp_errno_filename (pfile, CPP_DL_WARNING,
+			    file->path ? file->path : file->name);
     }
 }
 
--- libcpp/errors.c	(revision 230590)
+++ libcpp/errors.c	(revision 230591)
@@ -230,8 +230,18 @@  cpp_warning_with_line_syshdr (cpp_reader
 bool
 cpp_errno (cpp_reader *pfile, int level, const char *msgid)
 {
-  if (msgid[0] == '\0')
-    msgid = _("stdout");
+  return cpp_error (pfile, level, "%s: %s", _(msgid), xstrerror (errno));
+}
+
+/* Print a warning or error, depending on the value of LEVEL.  Include
+   information from errno.  Unlike cpp_errno, the argument is a filename
+   that is not localized, but "" is replaced with localized "stdout".  */
+
+bool
+cpp_errno_filename (cpp_reader *pfile, int level, const char *filename)
+{
+  if (filename[0] == '\0')
+    filename = _("stdout");
 
-  return cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno));
+  return cpp_error (pfile, level, "%s: %s", filename, xstrerror (errno));
 }