Hi!

I've backported following 46 patches from trunk to gcc-8-branch,
bootstrapped/regtested on x86_64-linux and i686-linux and committed.

        Jakub
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-20  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/88074
        PR middle-end/89415
        * toplev.c (do_compile): Double the emin/emax exponents to workaround
        buggy mpc_norm.

        * gcc.dg/pr88074-2.c: New test.

        2019-02-19  Richard Biener  <rguent...@suse.de>

        PR middle-end/88074
        * toplev.c (do_compile): Initialize mpfr's exponent range
        based on available float modes.

        * gcc.dg/pr88074.c: New testcase.

--- gcc/toplev.c        (revision 269014)
+++ gcc/toplev.c        (revision 269055)
@@ -2153,6 +2153,34 @@
        else
          int_n_enabled_p[i] = false;
 
+      /* Initialize mpfrs exponent range.  This is important to get
+         underflow/overflow in a reasonable timeframe.  */
+      machine_mode mode;
+      int min_exp = -1;
+      int max_exp = 1;
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
+       if (SCALAR_FLOAT_MODE_P (mode))
+         {
+           const real_format *fmt = REAL_MODE_FORMAT (mode);
+           if (fmt)
+             {
+               /* fmt->emin - fmt->p + 1 should be enough but the
+                  back-and-forth dance in real_to_decimal_for_mode we
+                  do for checking fails due to rounding effects then.  */
+               if ((fmt->emin - fmt->p) < min_exp)
+                 min_exp = fmt->emin - fmt->p;
+               if (fmt->emax > max_exp)
+                 max_exp = fmt->emax;
+             }
+         }
+      /* E.g. mpc_norm assumes it can square a number without bothering with
+        with range scaling, so until that is fixed, double the minimum
+        and maximum exponents, plus add some buffer for arithmetics
+        on the squared numbers.  */
+      if (mpfr_set_emin (2 * (min_exp - 1))
+         || mpfr_set_emax (2 * (max_exp + 1)))
+       sorry ("mpfr not configured to handle all float modes");
+
       /* Set up the back-end if requested.  */
       if (!no_backend)
        backend_init ();
--- gcc/testsuite/gcc.dg/pr88074.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr88074.c      (revision 269015)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+#include <complex.h>
+
+int main()
+{
+  _Complex double x;
+  __real x = 3.091e+8;
+  __imag x = -4.045e+8;
+  /* This used to spend huge amounts of compile-time inside mpc.  */
+  volatile _Complex double y = ctan (x);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/pr88074-2.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/pr88074-2.c    (revision 269055)
@@ -0,0 +1,17 @@
+/* PR middle-end/88074 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-add-options float128 } */
+/* { dg-require-effective-target float128 } */
+/* { dg-final { scan-tree-dump-not "link_error " "optimized" } } */
+
+extern void link_error (void);
+int
+main ()
+{
+  if (((__FLT128_MAX__ * 0.5 + __FLT128_MAX__ * 0.5i)
+       / (__FLT128_MAX__ * 0.25 + __FLT128_MAX__ * 0.25i))
+      != (_Complex _Float128) 2)
+    link_error ();
+  return 0;
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-20  Jakub Jelinek  <ja...@redhat.com>
                    David Malcolm  <dmalc...@redhat.com>

        PR middle-end/89091
        * fold-const.c (decode_field_reference): Return NULL_TREE if
        lang_hooks.types.type_for_size returns NULL.  Check it before
        overwriting *exp_.  Use return NULL_TREE instead of return 0.

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

--- gcc/fold-const.c    (revision 269055)
+++ gcc/fold-const.c    (revision 269056)
@@ -4280,7 +4280,7 @@ decode_field_reference (location_t loc,
      There are problems with FP fields since the type_for_size call
      below can fail for, e.g., XFmode.  */
   if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
-    return 0;
+    return NULL_TREE;
 
   /* We are interested in the bare arrangement of bits, so strip everything
      that doesn't affect the machine mode.  However, record the type of the
@@ -4296,7 +4296,7 @@ decode_field_reference (location_t loc,
       exp = TREE_OPERAND (exp, 0);
       STRIP_NOPS (exp); STRIP_NOPS (and_mask);
       if (TREE_CODE (and_mask) != INTEGER_CST)
-       return 0;
+       return NULL_TREE;
     }
 
   poly_int64 poly_bitsize, poly_bitpos;
@@ -4312,7 +4312,11 @@ decode_field_reference (location_t loc,
       || (! AGGREGATE_TYPE_P (TREE_TYPE (inner))
          && compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)),
                               *pbitpos + *pbitsize) < 0))
-    return 0;
+    return NULL_TREE;
+
+  unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
+  if (unsigned_type == NULL_TREE)
+    return NULL_TREE;
 
   *exp_ = exp;
 
@@ -4323,7 +4327,6 @@ decode_field_reference (location_t loc,
     *punsignedp = TYPE_UNSIGNED (outer_type);
 
   /* Compute the mask to access the bitfield.  */
-  unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
   precision = TYPE_PRECISION (unsigned_type);
 
   mask = build_int_cst_type (unsigned_type, -1);
--- gcc/testsuite/gcc.dg/torture/pr89091.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr89091.c      (revision 269056)
@@ -0,0 +1,10 @@
+/* PR middle-end/89091 */
+/* { dg-do compile { target int128 } } */
+
+struct S { unsigned __int128 s : 65; };
+
+int
+foo (struct S *x, int y)
+{
+  return y && x->s;
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-20  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/89412
        * expr.c (expand_assignment): If result is a MEM, use change_address
        instead of simplify_gen_subreg.

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

--- gcc/expr.c  (revision 269056)
+++ gcc/expr.c  (revision 269057)
@@ -5211,9 +5211,13 @@ expand_assignment (tree to, tree from, b
                }
              else
                {
-                 rtx from_rtx
-                   = simplify_gen_subreg (to_mode, result,
-                                          TYPE_MODE (TREE_TYPE (from)), 0);
+                 rtx from_rtx;
+                 if (MEM_P (result))
+                   from_rtx = change_address (result, to_mode, NULL_RTX);
+                 else
+                   from_rtx
+                     = simplify_gen_subreg (to_mode, result,
+                                            TYPE_MODE (TREE_TYPE (from)), 0);
                  if (from_rtx)
                    {
                      emit_move_insn (XEXP (to_rtx, 0),
--- gcc/testsuite/gcc.c-torture/compile/pr89412.c       (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89412.c       (revision 269057)
@@ -0,0 +1,16 @@
+/* PR middle-end/89412 */
+
+struct S { double a, b; } d;
+int e;
+double f;
+
+void
+foo ()
+{
+  _Complex double h;
+  while (e)
+    {
+      f = h;
+      *(struct S *) &h = d;
+    }
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-20  Jakub Jelinek  <ja...@redhat.com>

        PR c++/89405
        * decl.c (maybe_commonize_var): When clearing TREE_PUBLIC and
        DECL_COMMON, set DECL_INTERFACE_KNOWN.

        * g++.dg/cpp1z/inline-var5.C: New test.

--- gcc/cp/decl.c       (revision 269057)
+++ gcc/cp/decl.c       (revision 269058)
@@ -5634,6 +5634,7 @@ maybe_commonize_var (tree decl)
                 be merged.  */
              TREE_PUBLIC (decl) = 0;
              DECL_COMMON (decl) = 0;
+             DECL_INTERFACE_KNOWN (decl) = 1;
              const char *msg;
              if (DECL_INLINE_VAR_P (decl))
                msg = G_("sorry: semantics of inline variable "
--- gcc/testsuite/g++.dg/cpp1z/inline-var5.C    (nonexistent)
+++ gcc/testsuite/g++.dg/cpp1z/inline-var5.C    (revision 269058)
@@ -0,0 +1,11 @@
+// PR c++/89405
+// { dg-do compile { target c++17 } }
+// { dg-options "-fno-weak" }
+
+template <int N>
+struct S
+{
+  static constexpr int a = N;  // { dg-warning "semantics of inline variable" }
+};                             // { dg-message "you can work around this" "" { 
target *-*-* } .-1 }
+
+const int *x = &S<0>::a;
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-20  Jakub Jelinek  <ja...@redhat.com>

        PR c++/89403
        * decl2.c (c_parse_final_cleanups): Move TREE_ASM_WRITTEN setting
        for flag_syntax_only from here...
        * semantics.c (expand_or_defer_fn_1): ... here.

        * g++.dg/cpp0x/pr89403.C: New test.

--- gcc/cp/semantics.c  (revision 269058)
+++ gcc/cp/semantics.c  (revision 269059)
@@ -4352,7 +4352,12 @@ expand_or_defer_fn_1 (tree fn)
   /* There's no reason to do any of the work here if we're only doing
      semantic analysis; this code just generates RTL.  */
   if (flag_syntax_only)
-    return false;
+    {
+      /* Pretend that this function has been written out so that we don't try
+        to expand it again.  */
+      TREE_ASM_WRITTEN (fn) = 1;
+      return false;
+    }
 
   return true;
 }
--- gcc/cp/decl2.c      (revision 269058)
+++ gcc/cp/decl2.c      (revision 269059)
@@ -4965,11 +4965,6 @@ c_parse_final_cleanups (void)
              /* Generate RTL for this function now that we know we
                 need it.  */
              expand_or_defer_fn (decl);
-             /* If we're compiling -fsyntax-only pretend that this
-                function has been written out so that we don't try to
-                expand it again.  */
-             if (flag_syntax_only)
-               TREE_ASM_WRITTEN (decl) = 1;
              reconsider = true;
            }
        }
--- gcc/testsuite/g++.dg/cpp0x/pr89403.C        (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/pr89403.C        (revision 269059)
@@ -0,0 +1,18 @@
+// PR c++/89403
+// { dg-do compile { target c++11 } }
+// { dg-options "-Os -fsyntax-only" }
+
+template <typename T>
+struct A : T {
+  constexpr A() : T() { }
+};
+
+template <typename T>
+struct B {
+  A<T> b;
+  constexpr B() { }
+};
+
+struct C { struct {} s; };
+constexpr B<C> b{};
+constexpr C c = b.b;
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-28  Jakub Jelinek  <ja...@redhat.com>

        PR c/89520
        * convert.c (convert_to_real_1, convert_to_integer_1): Punt for
        builtins if they don't have a single scalar floating point argument.
        Formatting fixes.

        * gcc.dg/pr89520-1.c: New test.
        * gcc.dg/pr89520-2.c: New test.

--- gcc/convert.c       (revision 269272)
+++ gcc/convert.c       (revision 269273)
@@ -216,12 +216,15 @@ convert_to_real_1 (tree type, tree expr,
          CASE_MATHFN (FABS)
          CASE_MATHFN (LOGB)
 #undef CASE_MATHFN
+           if (call_expr_nargs (expr) != 1
+               || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
+             break;
            {
              tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0));
              tree newtype = type;
 
-             /* We have (outertype)sqrt((innertype)x).  Choose the wider mode 
from
-                the both as the safe type for operation.  */
+             /* We have (outertype)sqrt((innertype)x).  Choose the wider mode
+                from the both as the safe type for operation.  */
              if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
                newtype = TREE_TYPE (arg0);
 
@@ -618,7 +621,8 @@ convert_to_integer_1 (tree type, tree ex
        CASE_FLT_FN (BUILT_IN_ROUND):
        CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
          /* Only convert in ISO C99 mode and with -fno-math-errno.  */
-         if (!targetm.libc_has_function (function_c99_misc) || flag_errno_math)
+         if (!targetm.libc_has_function (function_c99_misc)
+             || flag_errno_math)
            break;
          if (outprec < TYPE_PRECISION (integer_type_node)
              || (outprec == TYPE_PRECISION (integer_type_node)
@@ -641,7 +645,8 @@ convert_to_integer_1 (tree type, tree ex
        CASE_FLT_FN (BUILT_IN_RINT):
        CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
          /* Only convert in ISO C99 mode and with -fno-math-errno.  */
-         if (!targetm.libc_has_function (function_c99_misc) || flag_errno_math)
+         if (!targetm.libc_has_function (function_c99_misc)
+             || flag_errno_math)
            break;
          if (outprec < TYPE_PRECISION (integer_type_node)
              || (outprec == TYPE_PRECISION (integer_type_node)
@@ -657,14 +662,20 @@ convert_to_integer_1 (tree type, tree ex
 
        CASE_FLT_FN (BUILT_IN_TRUNC):
        CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
-         return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0), dofold);
+         if (call_expr_nargs (s_expr) != 1
+             || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
+           break;
+         return convert_to_integer_1 (type, CALL_EXPR_ARG (s_expr, 0),
+                                      dofold);
 
        default:
          break;
        }
 
-      if (fn)
-        {
+      if (fn
+         && call_expr_nargs (s_expr) == 1
+         && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
+       {
          tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
          return convert_to_integer_1 (type, newexpr, dofold);
        }
@@ -694,7 +705,9 @@ convert_to_integer_1 (tree type, tree ex
          break;
        }
 
-      if (fn)
+      if (fn
+         && call_expr_nargs (s_expr) == 1
+         && SCALAR_FLOAT_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (s_expr, 0))))
         {
          tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
          return convert_to_integer_1 (type, newexpr, dofold);
--- gcc/testsuite/gcc.dg/pr89520-1.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89520-1.c    (revision 269273)
@@ -0,0 +1,13 @@
+/* PR c/89520 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -w" } */
+
+#define A(name) __typeof (__builtin_##name (0)) name (); long name##1 () { 
return name (); }
+#define B(name) A(name) A(name##f) A(name##l)
+B (ceil)
+B (floor)
+B (round)
+B (trunc)
+B (nearbyint)
+B (rint)
+B (logb)
--- gcc/testsuite/gcc.dg/pr89520-2.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89520-2.c    (revision 269273)
@@ -0,0 +1,42 @@
+/* PR c/89520 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -w" } */
+
+#define A(name) __typeof (__builtin_##name (0)) name (); \
+  float name##1 () { return name (); } \
+  double name##2 () { return name (); }
+#define B(name) A(name) A(name##l)
+B (cosh)
+B (exp)
+B (exp10)
+B (exp2)
+B (expm1)
+B (gamma)
+B (j0)
+B (j1)
+B (lgamma)
+B (pow10)
+B (sinh)
+B (tgamma)
+B (y0)
+B (y1)
+B (acos)
+B (acosh)
+B (asin)
+B (asinh)
+B (atan)
+B (atanh)
+B (cbrt)
+B (cos)
+B (erf)
+B (erfc)
+B (log)
+B (log10)
+B (log2)
+B (log1p)
+B (sin)
+B (tan)
+B (tanh)
+B (sqrt)
+B (fabs)
+B (logb)
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-02-28  Jakub Jelinek  <ja...@redhat.com>

        PR c/89521
        * gcc.dg/pr89521-1.c: New test.
        * gcc.dg/pr89521-2.c: New test.

--- gcc/testsuite/gcc.dg/pr89521-1.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89521-1.c    (revision 269280)
@@ -0,0 +1,13 @@
+/* PR c/89521 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -w" } */
+
+#define A(name) __typeof (__builtin_##name (0)) name (); long name##1 () { 
return name (1); }
+#define B(name) A(name) A(name##f) A(name##l)
+B (ceil)
+B (floor)
+B (round)
+B (trunc)
+B (nearbyint)
+B (rint)
+B (logb)
--- gcc/testsuite/gcc.dg/pr89521-2.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89521-2.c    (revision 269280)
@@ -0,0 +1,42 @@
+/* PR c/89521 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -w" } */
+
+#define A(name) __typeof (__builtin_##name (0)) name (); \
+  float name##1 () { return name (1); } \
+  double name##2 () { return name (1); }
+#define B(name) A(name) A(name##l)
+B (cosh)
+B (exp)
+B (exp10)
+B (exp2)
+B (expm1)
+B (gamma)
+B (j0)
+B (j1)
+B (lgamma)
+B (pow10)
+B (sinh)
+B (tgamma)
+B (y0)
+B (y1)
+B (acos)
+B (acosh)
+B (asin)
+B (asinh)
+B (atan)
+B (atanh)
+B (cbrt)
+B (cos)
+B (erf)
+B (erfc)
+B (log)
+B (log10)
+B (log2)
+B (log1p)
+B (sin)
+B (tan)
+B (tanh)
+B (sqrt)
+B (fabs)
+B (logb)
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-05  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/89590
        * builtins.c (maybe_emit_free_warning): Punt if free doesn't have
        exactly one argument.

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

--- gcc/builtins.c      (revision 269391)
+++ gcc/builtins.c      (revision 269392)
@@ -10604,6 +10604,9 @@ maybe_emit_sprintf_chk_warning (tree exp
 static void
 maybe_emit_free_warning (tree exp)
 {
+  if (call_expr_nargs (exp) != 1)
+    return;
+
   tree arg = CALL_EXPR_ARG (exp, 0);
 
   STRIP_NOPS (arg);
--- gcc/testsuite/gcc.dg/pr89590.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89590.c      (revision 269392)
@@ -0,0 +1,11 @@
+/* PR middle-end/89590 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -w" } */
+
+void free (void *);
+
+void
+foo (void)
+{
+  ((void (*)()) free) ();
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-05  Jakub Jelinek  <ja...@redhat.com>

        PR target/89587
        * config/rs6000/t-linux (MULTIARCH_DIRNAME): Set to non-empty only
        if_multiarch.

--- gcc/config/rs6000/t-linux   (revision 269395)
+++ gcc/config/rs6000/t-linux   (revision 269396)
@@ -4,7 +4,7 @@ ifeq (,$(filter $(with_cpu),$(SOFT_FLOAT
 ifneq (,$(findstring powerpc64,$(target)))
 MULTILIB_OSDIRNAMES := .=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
 else
-MULTIARCH_DIRNAME := powerpc-linux-gnu
+MULTIARCH_DIRNAME := $(call if_multiarch,powerpc-linux-gnu)
 endif
 ifneq (,$(findstring powerpcle,$(target)))
 MULTIARCH_DIRNAME := $(subst -linux,le-linux,$(MULTIARCH_DIRNAME))
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-06  Jakub Jelinek  <ja...@redhat.com>

        PR c++/87148
        * init.c (build_value_init_noctor): Ignore flexible array members.

        * g++.dg/ext/flexary34.C: New test.

--- gcc/cp/init.c       (revision 269433)
+++ gcc/cp/init.c       (revision 269434)
@@ -419,6 +419,15 @@ build_value_init_noctor (tree type, tsub
              if (ftype == error_mark_node)
                continue;
 
+             /* Ignore flexible array members for value initialization.  */
+             if (TREE_CODE (ftype) == ARRAY_TYPE
+                 && !COMPLETE_TYPE_P (ftype)
+                 && !TYPE_DOMAIN (ftype)
+                 && COMPLETE_TYPE_P (TREE_TYPE (ftype))
+                 && (next_initializable_field (DECL_CHAIN (field))
+                     == NULL_TREE))
+               continue;
+
              /* We could skip vfields and fields of types with
                 user-defined constructors, but I think that won't improve
                 performance at all; it should be simpler in general just
--- gcc/testsuite/g++.dg/ext/flexary34.C        (nonexistent)
+++ gcc/testsuite/g++.dg/ext/flexary34.C        (revision 269434)
@@ -0,0 +1,10 @@
+// PR c++/87148
+// { dg-do compile }
+// { dg-options "-pedantic" }
+
+struct Tst { int i; char t[]; };       // { dg-warning "forbids flexible array 
member" }
+
+Tst t {};                              // { dg-warning "extended initializer 
lists only available with" "" { target c++98_only } }
+Tst u = Tst();
+void foo () { Tst u = {}; }
+Tst *bar () { return new Tst (); }
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-08  Jakub Jelinek  <ja...@redhat.com>

        PR c++/82075
        * g++.dg/cpp1z/decomp49.C: New test.

--- gcc/testsuite/g++.dg/cpp1z/decomp49.C       (nonexistent)
+++ gcc/testsuite/g++.dg/cpp1z/decomp49.C       (revision 269504)
@@ -0,0 +1,14 @@
+// PR c++/82075
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct B { };
+struct D : B { int i; };
+
+int
+main ()
+{
+  auto [i] = D{};      // { dg-warning "only available with" "" { target 
c++14_down } }
+  if (i != 0)
+    __builtin_abort ();
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-09  Jakub Jelinek  <ja...@redhat.com>

        PR c/88568
        * attribs.c (handle_dll_attribute): Don't clear TREE_STATIC for
        dllimport on VAR_DECLs with RECORD_TYPE or UNION_TYPE DECL_CONTEXT.

        * g++.dg/other/pr88568.C: New test.

--- gcc/attribs.c       (revision 269524)
+++ gcc/attribs.c       (revision 269525)
@@ -1691,8 +1691,11 @@ handle_dll_attribute (tree * pnode, tree
             a function global scope, unless declared static.  */
          if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
            TREE_PUBLIC (node) = 1;
-         /* Clear TREE_STATIC because DECL_EXTERNAL is set.  */
-         TREE_STATIC (node) = 0;
+         /* Clear TREE_STATIC because DECL_EXTERNAL is set, unless
+            it is a C++ static data member.  */
+         if (DECL_CONTEXT (node) == NULL_TREE
+             || !RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (node)))
+           TREE_STATIC (node) = 0;
        }
 
       if (*no_add_attrs == false)
--- gcc/testsuite/g++.dg/other/pr88568.C        (nonexistent)
+++ gcc/testsuite/g++.dg/other/pr88568.C        (revision 269525)
@@ -0,0 +1,13 @@
+// PR c/88568
+// { dg-do compile }
+// { dg-require-dll "" }
+
+struct S {
+  __attribute__((dllimport)) static const char foo[];
+};
+
+int
+foo (int x)
+{
+  return S::foo[x];
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-11  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/89651
        * trans-openmp.c (gfc_omp_clause_default_ctor): Set TREE_NO_WARNING
        on decl if adding COND_EXPR for allocatable.
        (gfc_omp_clause_copy_ctor): Set TREE_NO_WARNING on dest.

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

--- gcc/fortran/trans-openmp.c  (revision 269597)
+++ gcc/fortran/trans-openmp.c  (revision 269598)
@@ -558,6 +558,9 @@ gfc_omp_clause_default_ctor (tree clause
                             build3_loc (input_location, COND_EXPR,
                                         void_type_node, cond, then_b,
                                         else_b));
+      /* Avoid -W*uninitialized warnings.  */
+      if (DECL_P (decl))
+       TREE_NO_WARNING (decl) = 1;
     }
   else
     gfc_add_expr_to_block (&block, then_b);
@@ -664,6 +667,9 @@ gfc_omp_clause_copy_ctor (tree clause, t
   gfc_add_expr_to_block (&block,
                         build3_loc (input_location, COND_EXPR,
                                     void_type_node, cond, then_b, else_b));
+  /* Avoid -W*uninitialized warnings.  */
+  if (DECL_P (dest))
+    TREE_NO_WARNING (dest) = 1;
 
   return gfc_finish_block (&block);
 }
--- gcc/testsuite/gfortran.dg/gomp/pr89651.f90  (nonexistent)
+++ gcc/testsuite/gfortran.dg/gomp/pr89651.f90  (revision 269598)
@@ -0,0 +1,21 @@
+! PR fortran/89651
+! { dg-do compile }
+! { dg-additional-options "-Wuninitialized" }
+
+program pr89651
+  integer :: n
+  real, allocatable :: t(:)
+  n = 10
+  allocate (t(n), source = 0.0)
+!$omp parallel firstprivate(t)
+  print *, sum (t) ! { dg-bogus "lbound' may be used uninitialized in this 
function" }
+                   ! { dg-bogus "ubound' may be used uninitialized in this 
function" "" { target *-*-* } .-1 }
+                   ! { dg-bogus "offset' may be used uninitialized in this 
function" "" { target *-*-* } .-2 }
+!$omp end parallel
+!$omp parallel private(t)
+  t = 0.0
+  print *, sum (t) ! { dg-bogus "lbound' may be used uninitialized in this 
function" }
+                   ! { dg-bogus "ubound' may be used uninitialized in this 
function" "" { target *-*-* } .-1 }
+                   ! { dg-bogus "offset' may be used uninitialized in this 
function" "" { target *-*-* } .-2 }
+!$omp end parallel
+end program pr89651
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-12  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/89663
        * builtins.c (expand_builtin_int_roundingfn,
        expand_builtin_int_roundingfn_2): Return NULL_RTX instead of
        gcc_unreachable if validate_arglist fails.

        * gcc.c-torture/compile/pr89663-1.c: New test.
        * gcc.c-torture/compile/pr89663-2.c: New test.

--- gcc/builtins.c      (revision 269604)
+++ gcc/builtins.c      (revision 269605)
@@ -2692,7 +2692,7 @@ expand_builtin_int_roundingfn (tree exp,
   tree arg;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
-    gcc_unreachable ();
+    return NULL_RTX;
 
   arg = CALL_EXPR_ARG (exp, 0);
 
@@ -2828,7 +2828,7 @@ expand_builtin_int_roundingfn_2 (tree ex
   enum built_in_function fallback_fn = BUILT_IN_NONE;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
-     gcc_unreachable ();
+    return NULL_RTX;
 
   arg = CALL_EXPR_ARG (exp, 0);
 
--- gcc/testsuite/gcc.c-torture/compile/pr89663-1.c     (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89663-1.c     (revision 269605)
@@ -0,0 +1,81 @@
+/* PR middle-end/89663 */
+
+int irint ();
+long lrint ();
+long long llrint ();
+int iround ();
+long lround ();
+long long llround ();
+int iceil ();
+long lceil ();
+long long llceil ();
+int ifloor ();
+long lfloor ();
+long long llfloor ();
+int irintf ();
+long lrintf ();
+long long llrintf ();
+int iroundf ();
+long lroundf ();
+long long llroundf ();
+int iceilf ();
+long lceilf ();
+long long llceilf ();
+int ifloorf ();
+long lfloorf ();
+long long llfloorf ();
+int irintl ();
+long lrintl ();
+long long llrintl ();
+int iroundl ();
+long lroundl ();
+long long llroundl ();
+int iceill ();
+long lceill ();
+long long llceill ();
+int ifloorl ();
+long lfloorl ();
+long long llfloorl ();
+
+void
+foo (long long *p)
+{
+  int n = 0;
+#define T(f) p[n++] = f (1);
+  T (irint)
+  T (lrint)
+  T (llrint)
+  T (iround)
+  T (lround)
+  T (llround)
+  T (iceil)
+  T (lceil)
+  T (llceil)
+  T (ifloor)
+  T (lfloor)
+  T (llfloor)
+  T (irintf)
+  T (lrintf)
+  T (llrintf)
+  T (iroundf)
+  T (lroundf)
+  T (llroundf)
+  T (iceilf)
+  T (lceilf)
+  T (llceilf)
+  T (ifloorf)
+  T (lfloorf)
+  T (llfloorf)
+  T (irintl)
+  T (lrintl)
+  T (llrintl)
+  T (iroundl)
+  T (lroundl)
+  T (llroundl)
+  T (iceill)
+  T (lceill)
+  T (llceill)
+  T (ifloorl)
+  T (lfloorl)
+  T (llfloorl)
+}
--- gcc/testsuite/gcc.c-torture/compile/pr89663-2.c     (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89663-2.c     (revision 269605)
@@ -0,0 +1,82 @@
+/* PR middle-end/89663 */
+
+int irint (double);
+long lrint (double);
+long long llrint (double);
+int iround (double);
+long lround (double);
+long long llround (double);
+int iceil (double);
+long lceil (double);
+long long llceil (double);
+int ifloor (double);
+long lfloor (double);
+long long llfloor (double);
+int irintf (float);
+long lrintf (float);
+long long llrintf (float);
+int iroundf (float);
+long lroundf (float);
+long long llroundf (float);
+int iceilf (float);
+long lceilf (float);
+long long llceilf (float);
+int ifloorf (float);
+long lfloorf (float);
+long long llfloorf (float);
+int irintl (long double);
+long lrintl (long double);
+long long llrintl (long double);
+int iroundl (long double);
+long lroundl (long double);
+long long llroundl (long double);
+int iceill (long double);
+long lceill (long double);
+long long llceill (long double);
+int ifloorl (long double);
+long lfloorl (long double);
+long long llfloorl (long double);
+
+void
+foo (long long *p)
+{
+  int (*fn) (int);
+  int n = 0;
+#define T(f) fn = (int (*) (int)) f; p[n++] = fn (1);
+  T (irint)
+  T (lrint)
+  T (llrint)
+  T (iround)
+  T (lround)
+  T (llround)
+  T (iceil)
+  T (lceil)
+  T (llceil)
+  T (ifloor)
+  T (lfloor)
+  T (llfloor)
+  T (irintf)
+  T (lrintf)
+  T (llrintf)
+  T (iroundf)
+  T (lroundf)
+  T (llroundf)
+  T (iceilf)
+  T (lceilf)
+  T (llceilf)
+  T (ifloorf)
+  T (lfloorf)
+  T (llfloorf)
+  T (irintl)
+  T (lrintl)
+  T (llrintl)
+  T (iroundl)
+  T (lroundl)
+  T (llroundl)
+  T (iceill)
+  T (lceill)
+  T (llceill)
+  T (ifloorl)
+  T (lfloorl)
+  T (llfloorl)
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-13  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/88588
        * omp-simd-clone.c (ipa_simd_modify_stmt_ops): Handle PHI args.
        (ipa_simd_modify_function_body): Handle PHIs.

        * c-c++-common/gomp/pr88588.c: New test.

--- gcc/omp-simd-clone.c        (revision 269635)
+++ gcc/omp-simd-clone.c        (revision 269636)
@@ -866,6 +866,18 @@ ipa_simd_modify_stmt_ops (tree *tp, int
 
   if (tp != orig_tp)
     {
+      if (gimple_code (info->stmt) == GIMPLE_PHI
+         && cand
+         && TREE_CODE (*orig_tp) == ADDR_EXPR
+         && TREE_CODE (TREE_OPERAND (*orig_tp, 0)) == PARM_DECL
+         && cand->alias_ptr_type)
+       {
+         gcc_assert (TREE_CODE (cand->alias_ptr_type) == SSA_NAME);
+         *orig_tp = cand->alias_ptr_type;
+         info->modified = true;
+         return NULL_TREE;
+       }
+
       repl = build_fold_addr_expr (repl);
       gimple *stmt;
       if (is_gimple_debug (info->stmt))
@@ -882,7 +894,18 @@ ipa_simd_modify_stmt_ops (tree *tp, int
          stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl)), repl);
          repl = gimple_assign_lhs (stmt);
        }
-      gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
+      gimple_stmt_iterator gsi;
+      if (gimple_code (info->stmt) == GIMPLE_PHI)
+       {
+         gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+         /* Cache SSA_NAME for next time.  */
+         if (cand
+             && TREE_CODE (*orig_tp) == ADDR_EXPR
+             && TREE_CODE (TREE_OPERAND (*orig_tp, 0)) == PARM_DECL)
+           cand->alias_ptr_type = repl;
+       }
+      else
+       gsi = gsi_for_stmt (info->stmt);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
       *orig_tp = repl;
     }
@@ -983,6 +1006,31 @@ ipa_simd_modify_function_body (struct cg
     {
       gimple_stmt_iterator gsi;
 
+      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
+         int i, n = gimple_phi_num_args (phi);
+         info.stmt = phi;
+         struct walk_stmt_info wi;
+         memset (&wi, 0, sizeof (wi));
+         info.modified = false;
+         wi.info = &info;
+         for (i = 0; i < n; ++i)
+           {
+             int walk_subtrees = 1;
+             tree arg = gimple_phi_arg_def (phi, i);
+             tree op = arg;
+             ipa_simd_modify_stmt_ops (&op, &walk_subtrees, &wi);
+             if (op != arg)
+               {
+                 SET_PHI_ARG_DEF (phi, i, op);
+                 gcc_assert (TREE_CODE (op) == SSA_NAME);
+                 if (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
+                   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op) = 1;
+               }
+           }
+       }
+
       gsi = gsi_start_bb (bb);
       while (!gsi_end_p (gsi))
        {
--- gcc/testsuite/c-c++-common/gomp/pr88588.c   (nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/pr88588.c   (revision 269636)
@@ -0,0 +1,18 @@
+/* PR middle-end/88588 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -O1" } */
+
+int *v;
+
+#pragma omp declare simd
+void
+foo (int x)
+{
+  int *a = &x;
+
+  for (;;)
+    {
+      *v = *a;
+      a = v;
+    }
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-13  Jakub Jelinek  <ja...@redhat.com>

        PR debug/89498
        * dwarf2out.c (size_of_die): For dw_val_class_view_list always use
        DWARF_OFFSET_SIZE.
        (value_format): For dw_val_class_view_list never use DW_FORM_loclistx.

--- gcc/dwarf2out.c     (revision 269660)
+++ gcc/dwarf2out.c     (revision 269661)
@@ -9369,7 +9369,6 @@ size_of_die (dw_die_ref die)
          }
          break;
        case dw_val_class_loc_list:
-       case dw_val_class_view_list:
          if (dwarf_split_debug_info && dwarf_version >= 5)
            {
              gcc_assert (AT_loc_list (a)->num_assigned);
@@ -9378,6 +9377,9 @@ size_of_die (dw_die_ref die)
           else
             size += DWARF_OFFSET_SIZE;
          break;
+       case dw_val_class_view_list:
+         size += DWARF_OFFSET_SIZE;
+         break;
        case dw_val_class_range_list:
          if (value_format (a) == DW_FORM_rnglistx)
            {
@@ -9751,12 +9753,12 @@ value_format (dw_attr_node *a)
          gcc_unreachable ();
        }
     case dw_val_class_loc_list:
-    case dw_val_class_view_list:
       if (dwarf_split_debug_info
          && dwarf_version >= 5
          && AT_loc_list (a)->num_assigned)
        return DW_FORM_loclistx;
       /* FALLTHRU */
+    case dw_val_class_view_list:
     case dw_val_class_range_list:
       /* For range lists in DWARF 5, use DW_FORM_rnglistx from .debug_info.dwo
         but in .debug_info use DW_FORM_sec_offset, which is shorter if we
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-14  Jakub Jelinek  <ja...@redhat.com>

        PR c++/89512
        * semantics.c (finish_qualified_id_expr): Reject variable templates.

        * g++.dg/cpp1y/var-templ61.C: New test.

--- gcc/cp/semantics.c  (revision 269671)
+++ gcc/cp/semantics.c  (revision 269672)
@@ -2112,6 +2112,14 @@ finish_qualified_id_expr (tree qualifyin
        expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
                                 complain);
     }
+  else if (!template_p
+          && TREE_CODE (expr) == TEMPLATE_DECL
+          && !DECL_FUNCTION_TEMPLATE_P (expr))
+    {
+      if (complain & tf_error)
+       error ("%qE missing template arguments", expr);
+      return error_mark_node;
+    }
   else
     {
       /* In a template, return a SCOPE_REF for most qualified-ids
--- gcc/testsuite/g++.dg/cpp1y/var-templ61.C    (nonexistent)
+++ gcc/testsuite/g++.dg/cpp1y/var-templ61.C    (revision 269672)
@@ -0,0 +1,20 @@
+// PR c++/89512
+// { dg-do compile { target c++14 } }
+
+struct A {
+  template <typename T>
+  static const int a = 0;
+};
+
+struct B {
+  template <typename T>
+  static int foo ()
+  {
+    return T::a;               // { dg-error "missing template arguments" }
+  }
+};
+
+int bar ()
+{
+  return B::foo<A> ();         // { dg-message "required from here" }
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-14  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/89703
        * tree-ssa-strlen.c (valid_builtin_call): Punt if stmt call types
        aren't compatible also with builtin_decl_explicit.  Check pure
        or non-pure status of BUILT_IN_STR{{,N}CMP,N{LEN,{CAT,CPY}{,_CHK}}}
        and BUILT_IN_STPNCPY{,_CHK}.

        * gcc.c-torture/compile/pr89703-1.c: New test.
        * gcc.c-torture/compile/pr89703-2.c: New test.

--- gcc/tree-ssa-strlen.c       (revision 269673)
+++ gcc/tree-ssa-strlen.c       (revision 269674)
@@ -996,10 +996,18 @@ valid_builtin_call (gimple *stmt)
     return false;
 
   tree callee = gimple_call_fndecl (stmt);
+  tree decl = builtin_decl_explicit (DECL_FUNCTION_CODE (callee));
+  if (decl
+      && decl != callee
+      && !gimple_builtin_call_types_compatible_p (stmt, decl))
+    return false;
+
   switch (DECL_FUNCTION_CODE (callee))
     {
     case BUILT_IN_MEMCMP:
     case BUILT_IN_MEMCMP_EQ:
+    case BUILT_IN_STRCMP:
+    case BUILT_IN_STRNCMP:
     case BUILT_IN_STRCHR:
     case BUILT_IN_STRCHR_CHKP:
     case BUILT_IN_STRLEN:
@@ -1024,6 +1032,8 @@ valid_builtin_call (gimple *stmt)
     case BUILT_IN_STPCPY_CHK:
     case BUILT_IN_STPCPY_CHKP:
     case BUILT_IN_STPCPY_CHK_CHKP:
+    case BUILT_IN_STPNCPY:
+    case BUILT_IN_STPNCPY_CHK:
     case BUILT_IN_STRCAT:
     case BUILT_IN_STRCAT_CHK:
     case BUILT_IN_STRCAT_CHKP:
@@ -1032,6 +1042,10 @@ valid_builtin_call (gimple *stmt)
     case BUILT_IN_STRCPY_CHK:
     case BUILT_IN_STRCPY_CHKP:
     case BUILT_IN_STRCPY_CHK_CHKP:
+    case BUILT_IN_STRNCAT:
+    case BUILT_IN_STRNCAT_CHK:
+    case BUILT_IN_STRNCPY:
+    case BUILT_IN_STRNCPY_CHK:
       /* The above functions should be neither const nor pure.  Punt if they
         aren't.  */
       if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE)
--- gcc/testsuite/gcc.c-torture/compile/pr89703-1.c     (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89703-1.c     (revision 269674)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/89703 */
+
+typedef __SIZE_TYPE__ size_t;
+extern char *strlen (const char *);
+extern char *strnlen (const char *, size_t);
+extern char c[2];
+
+void
+foo (char **q)
+{
+  q[0] = strlen (c);
+  q[1] = strnlen (c, 2);
+}
--- gcc/testsuite/gcc.c-torture/compile/pr89703-2.c     (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89703-2.c     (revision 269674)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/89703 */
+
+typedef __SIZE_TYPE__ size_t;
+extern void *memcpy (void *, const void *, size_t);
+extern char *strlen (const char *);
+extern char c[2];
+
+void
+foo (char **q)
+{
+  memcpy (c, "a", 2);
+  q[0] = strlen (c);
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-14  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/89679
        * expmed.c (expand_mult_const): Don't add a REG_EQUAL note if it
        would contain a paradoxical SUBREG.

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

--- gcc/expmed.c        (revision 269679)
+++ gcc/expmed.c        (revision 269680)
@@ -3356,13 +3356,20 @@ expand_mult_const (machine_mode mode, rt
              tem = gen_lowpart (nmode, op0);
            }
 
-         insn = get_last_insn ();
-         wide_int wval_so_far
-           = wi::uhwi (val_so_far,
-                       GET_MODE_PRECISION (as_a <scalar_mode> (nmode)));
-         rtx c = immed_wide_int_const (wval_so_far, nmode);
-         set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
-                           accum_inner);
+         /* Don't add a REG_EQUAL note if tem is a paradoxical SUBREG.
+            In that case, only the low bits of accum would be guaranteed to
+            be equal to the content of the REG_EQUAL note, the upper bits
+            can be anything.  */
+         if (!paradoxical_subreg_p (tem))
+           {
+             insn = get_last_insn ();
+             wide_int wval_so_far
+               = wi::uhwi (val_so_far,
+                           GET_MODE_PRECISION (as_a <scalar_mode> (nmode)));
+             rtx c = immed_wide_int_const (wval_so_far, nmode);
+             set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
+                               accum_inner);
+           }
        }
     }
 
--- gcc/testsuite/gcc.dg/pr89679.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89679.c      (revision 269680)
@@ -0,0 +1,26 @@
+/* PR rtl-optimization/89679 */
+/* { dg-do run } */
+/* { dg-options "-Og -frerun-cse-after-loop -fno-tree-fre" } */
+
+unsigned short g;
+
+void
+foo (unsigned long long x)
+{
+  if (x != 0xffff)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+#if __SIZEOF_SHORT__ == 2 && __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+  unsigned short d = 0;
+  unsigned long long x, c = ~0;
+  c = c >> d;
+  __builtin_memset (&d, c, 2);
+  x = d + g;
+  foo (x);
+#endif
+  return 0;
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-14  Jakub Jelinek  <ja...@redhat.com>

        PR ipa/89684
        * multiple_target.c (create_dispatcher_calls): Change
        references_to_redirect from vector of ipa_ref * to vector of ipa_ref.
        In the node->iterate_referring loop, push *ref rather than ref, call
        ref->remove_reference () and always pass 0 to iterate_referring.

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

--- gcc/multiple_target.c       (revision 269680)
+++ gcc/multiple_target.c       (revision 269681)
@@ -103,10 +103,16 @@ create_dispatcher_calls (struct cgraph_n
     inode->resolve_alias (cgraph_node::get (resolver_decl));
 
   auto_vec<cgraph_edge *> edges_to_redirect;
-  auto_vec<ipa_ref *> references_to_redirect;
+  /* We need to capture the references by value rather than just pointers to 
them
+     and remove them right away, as removing them later would invalidate what
+     some other reference pointers point to.  */
+  auto_vec<ipa_ref> references_to_redirect;
 
-  for (unsigned i = 0; node->iterate_referring (i, ref); i++)
-    references_to_redirect.safe_push (ref);
+  while (node->iterate_referring (0, ref))
+    {
+      references_to_redirect.safe_push (*ref);
+      ref->remove_reference ();
+    }
 
   /* We need to remember NEXT_CALLER as it could be modified in the loop.  */
   for (cgraph_edge *e = node->callers; e ; e = e->next_caller)
@@ -146,13 +152,11 @@ create_dispatcher_calls (struct cgraph_n
                }
 
              symtab_node *source = ref->referring;
-             ref->remove_reference ();
              source->create_reference (inode, IPA_REF_ADDR);
            }
          else if (ref->use == IPA_REF_ALIAS)
            {
              symtab_node *source = ref->referring;
-             ref->remove_reference ();
              source->create_reference (inode, IPA_REF_ALIAS);
              source->add_to_same_comdat_group (inode);
            }
--- gcc/testsuite/gcc.target/i386/pr89684.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr89684.c     (revision 269681)
@@ -0,0 +1,23 @@
+/* PR ipa/89684 */
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+
+void bar (int, void (*) (void));
+
+__attribute__((target_clones ("default", "avx")))
+void foo (void)
+{
+  bar (0, foo);
+  bar (0, foo);
+}
+
+__attribute__((target_clones ("default", "avx", "avx2")))
+void baz (void)
+{
+  bar (0, foo);
+  bar (0, foo);
+  bar (0, foo);
+  bar (0, foo);
+  bar (0, foo);
+  bar (0, foo);
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-15  Jakub Jelinek  <ja...@redhat.com>

        PR debug/89704
        * dwarf2out.c (add_const_value_attribute): Return false for MINUS,
        SIGN_EXTEND and ZERO_EXTEND.

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

--- gcc/dwarf2out.c     (revision 269699)
+++ gcc/dwarf2out.c     (revision 269700)
@@ -19670,6 +19670,9 @@ add_const_value_attribute (dw_die_ref di
 
     case HIGH:
     case CONST_FIXED:
+    case MINUS:
+    case SIGN_EXTEND:
+    case ZERO_EXTEND:
       return false;
 
     case MEM:
--- gcc/testsuite/gcc.dg/debug/pr89704.c        (nonexistent)
+++ gcc/testsuite/gcc.dg/debug/pr89704.c        (revision 269700)
@@ -0,0 +1,14 @@
+/* PR debug/89704 */
+/* { dg-do compile } */
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+int
+foo (void)
+{
+  lab1:;
+  lab2:;
+  static int i = (intptr_t) &&lab1 - (intptr_t) &&lab2;
+  static int j = (intptr_t) &&lab1 - (intptr_t) &&lab2;
+  return i;
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-19  Jakub Jelinek  <ja...@redhat.com>

        PR c/89734
        * c-decl.c (grokdeclarator): Call c_build_qualified_type on function
        return type even if quals_used is 0.  Formatting fixes.

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

--- gcc/c/c-decl.c      (revision 269788)
+++ gcc/c/c-decl.c      (revision 269789)
@@ -6611,10 +6611,12 @@ grokdeclarator (const struct c_declarato
                  quals_used &= TYPE_QUAL_ATOMIC;
                if (quals_used && VOID_TYPE_P (type) && really_funcdef)
                  pedwarn (specs_loc, 0,
-                          "function definition has qualified void return 
type");
+                          "function definition has qualified void "
+                          "return type");
                else
                  warning_at (specs_loc, OPT_Wignored_qualifiers,
-                          "type qualifiers ignored on function return type");
+                             "type qualifiers ignored on function "
+                             "return type");
 
                /* Ensure an error for restrict on invalid types; the
                   DR#423 resolution is not entirely clear about
@@ -6624,8 +6626,7 @@ grokdeclarator (const struct c_declarato
                    && (!POINTER_TYPE_P (type)
                        || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
                  error_at (loc, "invalid use of %<restrict%>");
-               if (quals_used)
-                 type = c_build_qualified_type (type, quals_used);
+               type = c_build_qualified_type (type, quals_used);
              }
            type_quals = TYPE_UNQUALIFIED;
 
--- gcc/testsuite/gcc.dg/pr89734.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr89734.c      (revision 269789)
@@ -0,0 +1,12 @@
+/* PR c/89734 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+typedef const int CI;
+typedef _Atomic int AI;
+
+CI foo (void);
+const int foo (void);
+
+AI baz (void);
+_Atomic int baz (void);
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-19  Jakub Jelinek  <ja...@redhat.com>

        PR target/89726
        * config/i386/i386.c (ix86_expand_floorceildf_32): In ceil
        compensation use x2 += 1 instead of x2 -= -1 and when honoring
        signed zeros, do another copysign after the compensation.

        * gcc.target/i386/fpprec-1.c (x): Add 6 new constants.
        (expect_round, expect_rint, expect_floor, expect_ceil, expect_trunc):
        Add expected results for them.

--- gcc/config/i386/i386.c      (revision 269789)
+++ gcc/config/i386/i386.c      (revision 269790)
@@ -45563,8 +45563,10 @@ ix86_expand_floorceildf_32 (rtx operand0
           x2 -= 1;
      Compensate.  Ceil:
         if (x2 < x)
-          x2 -= -1;
-        return x2;
+          x2 += 1;
+       if (HONOR_SIGNED_ZEROS (mode))
+         x2 = copysign (x2, x);
+       return x2;
    */
   machine_mode mode = GET_MODE (operand0);
   rtx xa, TWO52, tmp, one, res, mask;
@@ -45590,17 +45592,16 @@ ix86_expand_floorceildf_32 (rtx operand0
   /* xa = copysign (xa, operand1) */
   ix86_sse_copysign_to_positive (xa, xa, res, mask);
 
-  /* generate 1.0 or -1.0 */
-  one = force_reg (mode,
-                  const_double_from_real_value (do_floor
-                                                ? dconst1 : dconstm1, mode));
+  /* generate 1.0 */
+  one = force_reg (mode, const_double_from_real_value (dconst1, mode));
 
   /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
   tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
   emit_insn (gen_rtx_SET (tmp, gen_rtx_AND (mode, one, tmp)));
-  /* We always need to subtract here to preserve signed zero.  */
-  tmp = expand_simple_binop (mode, MINUS,
+  tmp = expand_simple_binop (mode, do_floor ? MINUS : PLUS,
                             xa, tmp, NULL_RTX, 0, OPTAB_DIRECT);
+  if (!do_floor && HONOR_SIGNED_ZEROS (mode))
+    ix86_sse_copysign_to_positive (tmp, tmp, res, mask);
   emit_move_insn (res, tmp);
 
   emit_label (label);
--- gcc/testsuite/gcc.target/i386/fpprec-1.c    (revision 269789)
+++ gcc/testsuite/gcc.target/i386/fpprec-1.c    (revision 269790)
@@ -11,6 +11,9 @@ double x[] = { __builtin_nan(""), __buil
        0x1.0000000000001p-1, 0x1.fffffffffffffp-2,
        0x1.0000000000001p+0, 0x1.fffffffffffffp-1,
        0x1.8000000000001p+0, 0x1.7ffffffffffffp+0,
+       -0x1.0000000000001p-1, -0x1.fffffffffffffp-2,
+       -0x1.0000000000001p+0, -0x1.fffffffffffffp-1,
+       -0x1.8000000000001p+0, -0x1.7ffffffffffffp+0,
        -0.0, 0.0, -0.5, 0.5, -1.0, 1.0, -1.5, 1.5, -2.0, 2.0,
        -2.5, 2.5 };
 #define NUM (sizeof(x)/sizeof(double))
@@ -19,6 +22,7 @@ double expect_round[] = { __builtin_nan(
        -0x1.fffffffffffffp+1023, 0x1.fffffffffffffp+1023,
        -0.0, 0.0,
        1.0, 0.0, 1.0, 1.0, 2.0, 1.0,
+       -1.0, -0.0, -1.0, -1.0, -2.0, -1.0,
        -0.0, 0.0, -1.0, 1.0, -1.0, 1.0, -2.0, 2.0, -2.0, 2.0,
        -3.0, 3.0 };
 
@@ -26,6 +30,7 @@ double expect_rint[] = { __builtin_nan("
         -0x1.fffffffffffffp+1023, 0x1.fffffffffffffp+1023,
         -0.0, 0.0,
         1.0, 0.0, 1.0, 1.0, 2.0, 1.0,
+        -1.0, -0.0, -1.0, -1.0, -2.0, -1.0,
         -0.0, 0.0, -0.0, 0.0, -1.0, 1.0, -2.0, 2.0, -2.0, 2.0,
         -2.0, 2.0 };
 
@@ -33,6 +38,7 @@ double expect_floor[] = { __builtin_nan(
         -0x1.fffffffffffffp+1023, 0x1.fffffffffffffp+1023,
         -1.0, 0.0,
         0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
+        -1.0, -1.0, -2.0, -1.0, -2.0, -2.0,
         -0.0, 0.0, -1.0, 0.0, -1.0, 1.0, -2.0, 1.0, -2.0, 2.0,
         -3.0, 2.0 };
 
@@ -40,6 +46,7 @@ double expect_ceil[] = { __builtin_nan("
         -0x1.fffffffffffffp+1023, 0x1.fffffffffffffp+1023,
         -0.0, 1.0,
         1.0, 1.0, 2.0, 1.0, 2.0, 2.0,
+        -0.0, -0.0, -1.0, -0.0, -1.0, -1.0,
         -0.0, 0.0, -0.0, 1.0, -1.0, 1.0, -1.0, 2.0, -2.0, 2.0,
         -2.0, 3.0 };
 
@@ -47,6 +54,7 @@ double expect_trunc[] = { __builtin_nan(
         -0x1.fffffffffffffp+1023, 0x1.fffffffffffffp+1023,
         -0.0, 0.0,
         0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
+        -0.0, -0.0, -1.0, -0.0, -1.0, -1.0,
         -0.0, 0.0, -0.0, 0.0, -1.0, 1.0, -1.0, 1.0, -2.0, 2.0,
         -2.0, 2.0 };
 
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-19  Jakub Jelinek  <ja...@redhat.com>

        PR target/89752
        * gimplify.c (gimplify_asm_expr): For output argument with
        TREE_ADDRESSABLE type, clear allows_reg if it allows memory, otherwise
        diagnose error.

        * g++.dg/ext/asm15.C: Check for particular diagnostic wording.
        * g++.dg/ext/asm16.C: Likewise.
        * g++.dg/ext/asm17.C: New test.

--- gcc/gimplify.c      (revision 269792)
+++ gcc/gimplify.c      (revision 269793)
@@ -6155,6 +6155,19 @@ gimplify_asm_expr (tree *expr_p, gimple_
          is_inout = false;
        }
 
+      /* If we can't make copies, we can only accept memory.  */
+      if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
+       {
+         if (allows_mem)
+           allows_reg = 0;
+         else
+           {
+             error ("impossible constraint in %<asm%>");
+             error ("non-memory output %d must stay in memory", i);
+             return GS_ERROR;
+           }
+       }
+
       if (!allows_reg && allows_mem)
        mark_addressable (TREE_VALUE (link));
 
--- gcc/testsuite/g++.dg/ext/asm15.C    (revision 269792)
+++ gcc/testsuite/g++.dg/ext/asm15.C    (revision 269793)
@@ -6,5 +6,6 @@ struct S { S (); ~S (); int s; };
 void
 foo (S &s)
 {
-  __asm volatile ("" : "+r" (s) : : "memory"); // { dg-error "" }
+  __asm volatile ("" : "+r" (s) : : "memory"); // { dg-error "impossible 
constraint" }
+                                               // { dg-error "must stay in 
memory" "" { target *-*-* } .-1 }
 }
--- gcc/testsuite/g++.dg/ext/asm16.C    (revision 269792)
+++ gcc/testsuite/g++.dg/ext/asm16.C    (revision 269793)
@@ -6,5 +6,6 @@ struct S { S (); ~S (); int s[64]; } s;
 void
 foo ()
 {
-  __asm volatile ("" : "=r" (s) : : "memory"); // { dg-error "" }
+  __asm volatile ("" : "=r" (s) : : "memory"); // { dg-error "impossible 
constraint" }
+                                               // { dg-error "must stay in 
memory" "" { target *-*-* } .-1 }
 }
--- gcc/testsuite/g++.dg/ext/asm17.C    (nonexistent)
+++ gcc/testsuite/g++.dg/ext/asm17.C    (revision 269793)
@@ -0,0 +1,11 @@
+// PR target/89752
+// { dg-do compile }
+
+struct A { A (); ~A (); short c; };
+
+void
+foo ()
+{
+  A a0, a1;
+  __asm volatile ("" : "+rm" (a0), "+rm" (a1));
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-19  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/89768
        * loop-unroll.c (unroll_loop_constant_iterations): Use gen_int_mode
        instead of GEN_INT.
        (unroll_loop_runtime_iterations): Likewise.

--- gcc/loop-unroll.c   (revision 269811)
+++ gcc/loop-unroll.c   (revision 269812)
@@ -652,7 +652,7 @@ unroll_loop_constant_iterations (struct
   if (loop->any_likely_upper_bound)
     loop->nb_iterations_likely_upper_bound
       = wi::udiv_trunc (loop->nb_iterations_likely_upper_bound, max_unroll + 
1);
-  desc->niter_expr = GEN_INT (desc->niter);
+  desc->niter_expr = gen_int_mode (desc->niter, desc->mode);
 
   /* Remove the edges.  */
   FOR_EACH_VEC_ELT (remove_edges, i, e)
@@ -1020,9 +1020,9 @@ unroll_loop_runtime_iterations (struct l
       preheader = split_edge (loop_preheader_edge (loop));
       /* Add in count of edge from switch block.  */
       preheader->count += iter_count;
-      branch_code = compare_and_jump_seq (copy_rtx (niter), GEN_INT (j), EQ,
-                                         block_label (preheader), p,
-                                         NULL);
+      branch_code = compare_and_jump_seq (copy_rtx (niter),
+                                         gen_int_mode (j, desc->mode), EQ,
+                                         block_label (preheader), p, NULL);
 
       /* We rely on the fact that the compare and jump cannot be optimized out,
         and hence the cfg we create is correct.  */
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-20  Jakub Jelinek  <ja...@redhat.com>

        PR target/89752
        * lra-constraints.c (process_alt_operands) <reg>: For BLKmode, don't
        update this_alternative nor this_alternative_set.

--- gcc/lra-constraints.c       (revision 269818)
+++ gcc/lra-constraints.c       (revision 269819)
@@ -2350,6 +2350,8 @@ process_alt_operands (int only_alternati
                  break;
 
                reg:
+                 if (mode == BLKmode)
+                   break;
                  this_alternative = reg_class_subunion[this_alternative][cl];
                  IOR_HARD_REG_SET (this_alternative_set,
                                    reg_class_contents[cl]);
@@ -2360,8 +2362,6 @@ process_alt_operands (int only_alternati
                      IOR_HARD_REG_SET (this_costly_alternative_set,
                                        reg_class_contents[cl]);
                    }
-                 if (mode == BLKmode)
-                   break;
                  winreg = true;
                  if (REG_P (op))
                    {
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-21  Jakub Jelinek  <ja...@redhat.com>

        PR c++/89767
        * parser.c (cp_parser_lambda_introducer): Add ids and first_capture_id
        variables, check for duplicates in this function.
        * lambda.c (add_capture): Don't check for duplicates nor use
        IDENTIFIER_MARKED.
        (register_capture_members): Don't clear IDENTIFIER_MARKED here.

        * g++.dg/cpp1y/lambda-init18.C: New test.
        * g++.dg/cpp1y/lambda-init19.C: New test.
        * g++.dg/cpp1y/pr89767.C: New test.

--- gcc/cp/parser.c     (revision 269859)
+++ gcc/cp/parser.c     (revision 269860)
@@ -10266,6 +10266,11 @@ cp_parser_lambda_introducer (cp_parser*
       first = false;
     }
 
+  hash_set<tree> *ids = NULL;
+#if GCC_VERSION >= 8000
+  char ids_buf[sizeof (hash_set<tree>) + __alignof__ (hash_set<tree>) - 1];
+#endif
+  tree first_capture_id = NULL_TREE;
   while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
     {
       cp_token* capture_token;
@@ -10301,11 +10306,14 @@ cp_parser_lambda_introducer (cp_parser*
            pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant "
                     "with by-copy capture default");
          cp_lexer_consume_token (parser->lexer);
-         add_capture (lambda_expr,
-                      /*id=*/this_identifier,
-                      /*initializer=*/finish_this_expr (),
-                      /*by_reference_p=*/true,
-                      explicit_init_p);
+         if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
+           pedwarn (input_location, 0,
+                    "already captured %qD in lambda expression",
+                    this_identifier);
+         else
+           add_capture (lambda_expr, /*id=*/this_identifier,
+                        /*initializer=*/finish_this_expr (),
+                        /*by_reference_p=*/true, explicit_init_p);
          continue;
        }
 
@@ -10319,11 +10327,14 @@ cp_parser_lambda_introducer (cp_parser*
                             "-std=c++17 or -std=gnu++17");
          cp_lexer_consume_token (parser->lexer);
          cp_lexer_consume_token (parser->lexer);
-         add_capture (lambda_expr,
-                      /*id=*/this_identifier,
-                      /*initializer=*/finish_this_expr (),
-                      /*by_reference_p=*/false,
-                      explicit_init_p);
+         if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
+           pedwarn (input_location, 0,
+                    "already captured %qD in lambda expression",
+                    this_identifier);
+         else
+           add_capture (lambda_expr, /*id=*/this_identifier,
+                        /*initializer=*/finish_this_expr (),
+                        /*by_reference_p=*/false, explicit_init_p);
          continue;
        }
 
@@ -10445,11 +10456,35 @@ cp_parser_lambda_introducer (cp_parser*
                     "default", capture_id);
        }
 
-      add_capture (lambda_expr,
-                  capture_id,
-                  capture_init_expr,
-                  /*by_reference_p=*/capture_kind == BY_REFERENCE,
-                  explicit_init_p);
+      /* Check for duplicates.
+        Optimize for the zero or one explicit captures cases and only create
+        the hash_set after adding second capture.  */
+      bool found = false;
+      if (ids && ids->elements ())
+       found = ids->add (capture_id);
+      else if (first_capture_id == NULL_TREE)
+       first_capture_id = capture_id;
+      else if (capture_id == first_capture_id)
+       found = true;
+      else
+       {
+#if GCC_VERSION >= 8000
+         ids = new (ids_buf
+                    + (-(uintptr_t) ids_buf
+                       & (__alignof__ (hash_set <tree>) - 1))) hash_set <tree>;
+#else
+         ids = new hash_set <tree>;
+#endif
+         ids->add (first_capture_id);
+         ids->add (capture_id);
+       }
+      if (found)
+       pedwarn (input_location, 0,
+                "already captured %qD in lambda expression", capture_id);
+      else
+       add_capture (lambda_expr, capture_id, capture_init_expr,
+                    /*by_reference_p=*/capture_kind == BY_REFERENCE,
+                    explicit_init_p);
 
       /* If there is any qualification still in effect, clear it
         now; we will be starting fresh with the next capture.  */
@@ -10458,6 +10493,13 @@ cp_parser_lambda_introducer (cp_parser*
       parser->object_scope = NULL_TREE;
     }
 
+  if (ids)
+#if GCC_VERSION >= 8000
+    ids->~hash_set <tree> ();
+#else
+    delete ids;
+#endif
+
   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 }
 
--- gcc/cp/lambda.c     (revision 269859)
+++ gcc/cp/lambda.c     (revision 269860)
@@ -601,19 +601,6 @@ add_capture (tree lambda, tree id, tree
          IDENTIFIER_LENGTH (id) + 1);
   name = get_identifier (buf);
 
-  /* If TREE_TYPE isn't set, we're still in the introducer, so check
-     for duplicates.  */
-  if (!LAMBDA_EXPR_CLOSURE (lambda))
-    {
-      if (IDENTIFIER_MARKED (name))
-       {
-         pedwarn (input_location, 0,
-                  "already captured %qD in lambda expression", id);
-         return NULL_TREE;
-       }
-      IDENTIFIER_MARKED (name) = true;
-    }
-
   if (variadic)
     type = make_pack_expansion (type);
 
@@ -674,8 +661,6 @@ register_capture_members (tree captures)
   if (PACK_EXPANSION_P (field))
     field = PACK_EXPANSION_PATTERN (field);
 
-  /* We set this in add_capture to avoid duplicates.  */
-  IDENTIFIER_MARKED (DECL_NAME (field)) = false;
   finish_member_declaration (field);
 }
 
--- gcc/testsuite/g++.dg/cpp1y/pr89767.C        (nonexistent)
+++ gcc/testsuite/g++.dg/cpp1y/pr89767.C        (revision 269860)
@@ -0,0 +1,32 @@
+// PR c++/89767
+// { dg-do compile { target c++14 } }
+// { dg-options "-O2 -Wall" }
+
+template <typename d> struct e { using g = d; };
+template <typename d, template <typename> class> using h = e<d>;
+template <typename d, template <typename> class i>
+using j = typename h<d, i>::g;
+template <typename c> int k(c);
+template <typename...> class au;
+struct l { template <typename c> using m = typename c::f; };
+struct s : l { using af = j<au<int, int> *, m>; };
+template <unsigned long, typename> struct o;
+template <long p, typename c> using q = typename o<p, c>::g;
+template <typename> struct r;
+template <typename c> struct r<c *> { typedef c aj; };
+template <typename ak, typename> struct al { typename r<ak>::aj operator*(); 
void operator++(); };
+template <typename am, typename an, typename ao>
+bool operator!=(al<am, ao>, al<an, ao>);
+template <unsigned long, typename...> struct ap;
+template <unsigned long aq, typename ar, typename... as>
+struct ap<aq, ar, as...> : ap<1, as...> {};
+template <unsigned long aq, typename ar> struct ap<aq, ar> {};
+template <typename... at> class au : public ap<0, at...> {};
+template <unsigned long p, typename ar, typename... as>
+struct o<p, au<ar, as...>> : o<p - 1, au<as...>> {};
+template <typename ar, typename... as> struct o<0, au<ar, as...>> { typedef ar 
g; };
+template <long p, typename ar> constexpr ar av(ap<p, ar> __t) { return ar (); }
+template <int p, typename... at> constexpr q<p, au<at...>> aw(au<at...> __t) { 
av<p>(__t); return q<p, au<at...>> (); }
+struct bg { typedef s::af af; };
+struct F { typedef al<bg::af, int> bk; bk begin(); bk end(); };
+void bo() { int t = 0; F cv; for (auto bp : cv) [t, n = k(aw<1>(bp))] {}; }
--- gcc/testsuite/g++.dg/cpp1y/lambda-init18.C  (nonexistent)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-init18.C  (revision 269860)
@@ -0,0 +1,12 @@
+// PR c++/89767
+// { dg-do compile { target c++14 } }
+
+void bar (int);
+
+void
+foo ()
+{
+  int x = 0;
+  auto z = [x, y = [x] { bar (x); }] { y (); bar (x); };
+  z ();
+}
--- gcc/testsuite/g++.dg/cpp1y/lambda-init19.C  (nonexistent)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-init19.C  (revision 269860)
@@ -0,0 +1,15 @@
+// PR c++/89767
+// { dg-do compile { target c++14 } }
+
+void bar (int);
+
+void
+foo ()
+{
+  int x = 0;
+  int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
+  auto z = [x, y = [x] { bar (x); }, x] { y (); bar (x); };    // { dg-error 
"already captured 'x' in lambda expression" }
+  auto w = [x, a, b, c, d, y = [x] { bar (x); }, e, f, g, h, x] { y (); bar (x 
+ a + b + c + d + e + f + g + h); };    // { dg-error "already captured 'x' in 
lambda expression" }
+  z ();
+  w ();
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-22  Jakub Jelinek  <ja...@redhat.com>

        PR c++/60702
        * cp-tree.h (get_tls_wrapper_fn): Remove declaration.
        (maybe_get_tls_wrapper_call): Declare.
        * decl2.c (get_tls_wrapper_fn): Make static.
        (maybe_get_tls_wrapper_call): New function.
        * typeck.c (build_class_member_access_expr): Handle accesses to TLS
        variables.
        * semantics.c (finish_qualified_id_expr): Likewise.
        (finish_id_expression_1): Use maybe_get_tls_wrapper_call.
        * pt.c (tsubst_copy_and_build): Likewise.

        * g++.dg/tls/thread_local11.C: New test.
        * g++.dg/tls/thread_local11.h: New test.
        * g++.dg/tls/thread_local12a.C: New test.
        * g++.dg/tls/thread_local12b.C: New test.
        * g++.dg/tls/thread_local12c.C: New test.
        * g++.dg/tls/thread_local12d.C: New test.
        * g++.dg/tls/thread_local12e.C: New test.
        * g++.dg/tls/thread_local12f.C: New test.
        * g++.dg/tls/thread_local12g.C: New test.
        * g++.dg/tls/thread_local12h.C: New test.
        * g++.dg/tls/thread_local12i.C: New test.
        * g++.dg/tls/thread_local12j.C: New test.
        * g++.dg/tls/thread_local12k.C: New test.
        * g++.dg/tls/thread_local12l.C: New test.

--- gcc/cp/typeck.c     (revision 269874)
+++ gcc/cp/typeck.c     (revision 269875)
@@ -2443,6 +2443,12 @@ build_class_member_access_expr (cp_expr
       /* A static data member.  */
       result = member;
       mark_exp_read (object);
+
+      if (tree wrap = maybe_get_tls_wrapper_call (result))
+       /* Replace an evaluated use of the thread_local variable with
+          a call to its wrapper.  */
+       result = wrap;
+
       /* If OBJECT has side-effects, they are supposed to occur.  */
       if (TREE_SIDE_EFFECTS (object))
        result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
--- gcc/cp/pt.c (revision 269874)
+++ gcc/cp/pt.c (revision 269875)
@@ -19403,17 +19403,10 @@ tsubst_copy_and_build (tree t,
       {
        tree r = tsubst_copy (t, args, complain, in_decl);
        /* ??? We're doing a subset of finish_id_expression here.  */
-       if (VAR_P (r)
-           && !processing_template_decl
-           && !cp_unevaluated_operand
-           && (TREE_STATIC (r) || DECL_EXTERNAL (r))
-           && CP_DECL_THREAD_LOCAL_P (r))
-         {
-           if (tree wrap = get_tls_wrapper_fn (r))
-             /* Replace an evaluated use of the thread_local variable with
-                a call to its wrapper.  */
-             r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
-         }
+       if (tree wrap = maybe_get_tls_wrapper_call (r))
+         /* Replace an evaluated use of the thread_local variable with
+            a call to its wrapper.  */
+         r = wrap;
        else if (outer_automatic_var_p (r))
          r = process_outer_var_ref (r, complain);
 
--- gcc/cp/semantics.c  (revision 269874)
+++ gcc/cp/semantics.c  (revision 269875)
@@ -2143,6 +2143,8 @@ finish_qualified_id_expr (tree qualifyin
        expr = build_qualified_name (TREE_TYPE (expr),
                                     qualifying_class, expr,
                                     template_p);
+      else if (tree wrap = maybe_get_tls_wrapper_call (expr))
+       expr = wrap;
 
       expr = convert_from_reference (expr);
     }
@@ -3788,18 +3790,10 @@ finish_id_expression_1 (tree id_expressi
          *non_integral_constant_expression_p = true;
        }
 
-      tree wrap;
-      if (VAR_P (decl)
-         && !cp_unevaluated_operand
-         && !processing_template_decl
-         && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
-         && CP_DECL_THREAD_LOCAL_P (decl)
-         && (wrap = get_tls_wrapper_fn (decl)))
-       {
-         /* Replace an evaluated use of the thread_local variable with
-            a call to its wrapper.  */
-         decl = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
-       }
+      if (tree wrap = maybe_get_tls_wrapper_call (decl))
+       /* Replace an evaluated use of the thread_local variable with
+          a call to its wrapper.  */
+       decl = wrap;
       else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
               && !dependent_p
               && variable_template_p (TREE_OPERAND (decl, 0)))
--- gcc/cp/decl2.c      (revision 269874)
+++ gcc/cp/decl2.c      (revision 269875)
@@ -3442,7 +3442,7 @@ get_tls_init_fn (tree var)
    VAR and then returns a reference to VAR.  The wrapper function is used
    in place of VAR everywhere VAR is mentioned.  */
 
-tree
+static tree
 get_tls_wrapper_fn (tree var)
 {
   /* Only C++11 TLS vars need this wrapper fn.  */
@@ -3496,6 +3496,22 @@ get_tls_wrapper_fn (tree var)
   return fn;
 }
 
+/* If EXPR is a thread_local variable that should be wrapped by init
+   wrapper function, return a call to that function, otherwise return
+   NULL.  */
+
+tree
+maybe_get_tls_wrapper_call (tree expr)
+{
+  if (VAR_P (expr)
+      && !processing_template_decl
+      && !cp_unevaluated_operand
+      && CP_DECL_THREAD_LOCAL_P (expr))
+    if (tree wrap = get_tls_wrapper_fn (expr))
+      return build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+  return NULL;
+}
+
 /* At EOF, generate the definition for the TLS wrapper function FN:
 
    T& var_wrapper() {
--- gcc/cp/cp-tree.h    (revision 269874)
+++ gcc/cp/cp-tree.h    (revision 269875)
@@ -6513,7 +6513,7 @@ extern tree cp_build_parm_decl                    (tree,
 extern tree get_guard                          (tree);
 extern tree get_guard_cond                     (tree, bool);
 extern tree set_guard                          (tree);
-extern tree get_tls_wrapper_fn                 (tree);
+extern tree maybe_get_tls_wrapper_call         (tree);
 extern void mark_needed                                (tree);
 extern bool decl_needed_p                      (tree);
 extern void note_vague_linkage_fn              (tree);
--- gcc/testsuite/g++.dg/tls/thread_local11.C   (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local11.C   (revision 269875)
@@ -0,0 +1,48 @@
+// PR c++/60702
+// { dg-do compile { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+// { dg-additional-options "-fdump-tree-gimple" }
+// { dg-final { scan-tree-dump-times "_ZTW2s1" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTW2s2" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTW2s3" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTW2s4" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u1E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u2E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u3E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u4E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u5E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u6E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u7E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTWN1T2u8E" 2 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" } }
+
+#include "thread_local11.h"
+
+void
+foo ()
+{
+  f1 ();
+  f2 ();
+  f3 ();
+  f4 ();
+  f5 ();
+  f6 ();
+  f7<0> ();
+  f8<0> ();
+  f9<0> ();
+  f10<0> ();
+  f11<0> ();
+  f12<0> ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local11.h   (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local11.h   (revision 269875)
@@ -0,0 +1,26 @@
+// PR c++/60702
+
+extern "C" void abort ();
+struct S { S () { i = 42; }; int i; };
+thread_local S s1, s2, s3, s4;
+struct T { static thread_local S u1, u2, u3, u4, u5, u6, u7, u8; int i; } t;
+thread_local S T::u1, T::u2, T::u3, T::u4, T::u5, T::u6, T::u7, T::u8;
+
+S *f1 () { return &s1; }
+int *f2 () { return &s2.i; }
+S *f3 () { return &t.u1; }
+int *f4 () { return &t.u2.i; }
+S *f5 () { return &T::u3; }
+int *f6 () { return &T::u4.i; }
+template <int N>
+S *f7 () { return &s3; }
+template <int N>
+int *f8 () { return &s4.i; }
+template <int N>
+S *f9 () { return &t.u5; }
+template <int N>
+int *f10 () { return &t.u6.i; }
+template <int N>
+S *f11 () { return &T::u7; }
+template <int N>
+int *f12 () { return &T::u8.i; }
--- gcc/testsuite/g++.dg/tls/thread_local12a.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12a.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f1 ()->i != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12b.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12b.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f2 () != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12c.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12c.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f3 ()->i != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12d.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12d.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f4 () != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12e.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12e.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f5 ()->i != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12f.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12f.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f6 () != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12g.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12g.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f7<0> ()->i != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12h.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12h.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f8<0> () != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12i.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12i.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f9<0> ()->i != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12j.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12j.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f10<0> () != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12k.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12k.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (f11<0> ()->i != 42) abort ();
+}
--- gcc/testsuite/g++.dg/tls/thread_local12l.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local12l.C  (revision 269875)
@@ -0,0 +1,12 @@
+// PR c++/60702
+// { dg-do run { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-effective-target tls_runtime }
+
+#include "thread_local11.h"
+
+int
+main ()
+{
+  if (*f12<0> () != 42) abort ();
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-25  Jakub Jelinek  <ja...@redhat.com>

        PR c++/60702
        * g++.dg/tls/thread_local11.C: Remove scan-tree-dump-times directives
        for _ZTH* calls.
        * g++.dg/tls/thread_local11a.C: New test.

--- gcc/testsuite/g++.dg/tls/thread_local11.C   (revision 269911)
+++ gcc/testsuite/g++.dg/tls/thread_local11.C   (revision 269912)
@@ -15,18 +15,6 @@
 // { dg-final { scan-tree-dump-times "_ZTWN1T2u6E" 2 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTWN1T2u7E" 2 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTWN1T2u8E" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" } }
 
 #include "thread_local11.h"
 
--- gcc/testsuite/g++.dg/tls/thread_local11a.C  (nonexistent)
+++ gcc/testsuite/g++.dg/tls/thread_local11a.C  (revision 269912)
@@ -0,0 +1,20 @@
+// PR c++/60702
+// { dg-do compile { target c++11 } }
+// { dg-add-options tls }
+// { dg-require-alias "" }
+// { dg-require-effective-target tls_runtime }
+// { dg-additional-options "-fdump-tree-gimple" }
+// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" } }
+
+#include "thread_local11.C"
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-26  Jakub Jelinek  <ja...@redhat.com>

        PR c++/89796
        * semantics.c (finish_omp_atomic): Add warning_sentinel for
        -Wunused-value around finish_expr_stmt call.

        * g++.dg/gomp/pr89796.C: New test.
        * gcc.dg/gomp/pr89796.c: New test.

--- gcc/cp/semantics.c  (revision 269932)
+++ gcc/cp/semantics.c  (revision 269933)
@@ -8462,6 +8462,11 @@ finish_omp_atomic (enum tree_code code,
       stmt = build2 (OMP_ATOMIC, void_type_node, integer_zero_node, stmt);
       OMP_ATOMIC_SEQ_CST (stmt) = seq_cst;
     }
+
+  /* Avoid -Wunused-value warnings here, the whole construct has side-effects
+     and even if it might be wrapped from fold-const.c or c-omp.c wrapped
+     in some tree that appears to be unused, the value is not unused.  */
+  warning_sentinel w (warn_unused_value);
   finish_expr_stmt (stmt);
 }
 
--- gcc/testsuite/gcc.dg/gomp/pr89796.c (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr89796.c (revision 269933)
@@ -0,0 +1,23 @@
+/* PR c++/89796 */
+/* { dg-do compile } */
+/* { dg-additional-options "-Wunused-value" } */
+
+int
+f1 (int *p)
+{
+  int r;
+  #pragma omp atomic capture           /* { dg-bogus "value computed is not 
used" } */
+  { r = *p; (*p)++; }
+  return r;
+}
+
+int
+f2 (int *p)
+{
+  int s
+    = ({ int r;
+        #pragma omp atomic capture     /* { dg-bogus "value computed is not 
used" } */
+        { r = *p; (*p)++; }
+        r; });
+  return s;
+}
--- gcc/testsuite/g++.dg/gomp/pr89796.C (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr89796.C (revision 269933)
@@ -0,0 +1,53 @@
+// PR c++/89796
+// { dg-do compile }
+// { dg-additional-options "-Wunused-value" }
+
+int
+f1 (int &c)
+{
+  int r;
+  #pragma omp atomic capture   // { dg-bogus "value computed is not used" }
+  { r = c; c++; }
+  return r;
+}
+
+template <int N>
+int
+f2 (int &c)
+{
+  int r;
+  #pragma omp atomic capture   // { dg-bogus "value computed is not used" }
+  { r = c; c++; }
+  return r;
+}
+
+int
+f3 (int &c)
+{
+  return f2 <0> (c);
+}
+
+int
+f4 (int *p)
+{
+  int r;
+  #pragma omp atomic capture   // { dg-bogus "value computed is not used" }
+  { r = *p; (*p)++; }
+  return r;
+}
+
+template <int N>
+int
+f5 (int *p)
+{
+  int r;
+  #pragma omp atomic capture   // { dg-bogus "value computed is not used" }
+  { r = *p; (*p)++; }
+  return r;
+}
+
+int
+f6 (int *p)
+{
+  return f5 <0> (p);
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-28  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/89621
        * tree-inline.h (struct copy_body_data): Add
        dont_remap_vla_if_no_change flag.
        * tree-inline.c (remap_type_3, remap_type_2): New functions.
        (remap_type): Don't remap vla types if id->dont_remap_vla_if_no_change
        and remap_type_2 returns false.
        * omp-low.c (new_omp_context): Set ctx->cb.dont_remap_vla_if_no_change.

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

--- gcc/omp-low.c       (revision 270008)
+++ gcc/omp-low.c       (revision 270009)
@@ -851,6 +851,7 @@ new_omp_context (gimple *stmt, omp_conte
       ctx->cb.copy_decl = omp_copy_decl;
       ctx->cb.eh_lp_nr = 0;
       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
+      ctx->cb.dont_remap_vla_if_no_change = true;
       ctx->depth = 1;
     }
 
--- gcc/tree-inline.c   (revision 270008)
+++ gcc/tree-inline.c   (revision 270009)
@@ -598,6 +598,92 @@ remap_type_1 (tree type, copy_body_data
   return new_tree;
 }
 
+/* Helper function for remap_type_2, called through walk_tree.  */
+
+static tree
+remap_type_3 (tree *tp, int *walk_subtrees, void *data)
+{
+  copy_body_data *id = (copy_body_data *) data;
+
+  if (TYPE_P (*tp))
+    *walk_subtrees = 0;
+
+  else if (DECL_P (*tp) && remap_decl (*tp, id) != *tp)
+    return *tp;
+
+  return NULL_TREE;
+}
+
+/* Return true if TYPE needs to be remapped because remap_decl on any
+   needed embedded decl returns something other than that decl.  */
+
+static bool
+remap_type_2 (tree type, copy_body_data *id)
+{
+  tree t;
+
+#define RETURN_TRUE_IF_VAR(T) \
+  do                                                           \
+    {                                                          \
+      tree _t = (T);                                           \
+      if (_t)                                                  \
+       {                                                       \
+         if (DECL_P (_t) && remap_decl (_t, id) != _t)         \
+           return true;                                        \
+         if (!TYPE_SIZES_GIMPLIFIED (type)                     \
+             && walk_tree (&_t, remap_type_3, id, NULL))       \
+           return true;                                        \
+       }                                                       \
+    }                                                          \
+  while (0)
+
+  switch (TREE_CODE (type))
+    {
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+    case FUNCTION_TYPE:
+    case METHOD_TYPE:
+      return remap_type_2 (TREE_TYPE (type), id);
+
+    case INTEGER_TYPE:
+    case REAL_TYPE:
+    case FIXED_POINT_TYPE:
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+      RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
+      RETURN_TRUE_IF_VAR (TYPE_MAX_VALUE (type));
+      return false;
+
+    case ARRAY_TYPE:
+      if (remap_type_2 (TREE_TYPE (type), id)
+         || (TYPE_DOMAIN (type) && remap_type_2 (TYPE_DOMAIN (type), id)))
+       return true;
+      break;
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+      for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
+       if (TREE_CODE (t) == FIELD_DECL)
+         {
+           RETURN_TRUE_IF_VAR (DECL_FIELD_OFFSET (t));
+           RETURN_TRUE_IF_VAR (DECL_SIZE (t));
+           RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));
+           if (TREE_CODE (type) == QUAL_UNION_TYPE)
+             RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
+         }
+      break;
+
+    default:
+      return false;
+    }
+
+  RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
+  RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (type));
+  return false;
+#undef RETURN_TRUE_IF_VAR
+}
+
 tree
 remap_type (tree type, copy_body_data *id)
 {
@@ -613,7 +699,10 @@ remap_type (tree type, copy_body_data *i
     return *node;
 
   /* The type only needs remapping if it's variably modified.  */
-  if (! variably_modified_type_p (type, id->src_fn))
+  if (! variably_modified_type_p (type, id->src_fn)
+      /* Don't remap if copy_decl method doesn't always return a new
+        decl and for all embedded decls returns the passed in decl.  */
+      || (id->dont_remap_vla_if_no_change && !remap_type_2 (type, id)))
     {
       insert_decl_map (id, type, type);
       return type;
--- gcc/tree-inline.h   (revision 270008)
+++ gcc/tree-inline.h   (revision 270009)
@@ -119,6 +119,13 @@ struct copy_body_data
   /* > 0 if we are remapping a type currently.  */
   int remapping_type_depth;
 
+  /* Usually copy_decl callback always creates new decls, in that case
+     we want to remap all variably_modified_type_p types.  If this flag
+     is set, remap_type will do further checks to see if remap_decl
+     of any decls mentioned in the type will remap to anything but itself
+     and only in that case will actually remap the type.  */
+  bool dont_remap_vla_if_no_change;
+
   /* A function to be called when duplicating BLOCK nodes.  */
   void (*transform_lang_insert_block) (tree);
 
--- gcc/testsuite/gfortran.dg/gomp/pr89621.f90  (nonexistent)
+++ gcc/testsuite/gfortran.dg/gomp/pr89621.f90  (revision 270009)
@@ -0,0 +1,18 @@
+! PR middle-end/89621
+! { dg-do compile }
+
+subroutine sub(str)
+  character(*), intent(in) :: str
+end subroutine sub
+
+program pr89621
+  implicit none
+  integer i
+  character(len=:), allocatable :: str
+  str = "test"
+  !$omp parallel do
+  do i = 1, 10
+    call sub(str)
+  enddo
+  !$omp end parallel do
+end program pr89621
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-29  Jakub Jelinek  <ja...@redhat.com>

        PR c/89872
        * gimplify.c (gimplify_compound_literal_expr): Don't optimize a
        non-addressable complit into its initializer if it is volatile.

        * gcc.dg/tree-ssa/pr89872.c: New test.

--- gcc/gimplify.c      (revision 270022)
+++ gcc/gimplify.c      (revision 270023)
@@ -4665,6 +4665,7 @@ gimplify_compound_literal_expr (tree *ex
      otherwise we'd generate a new temporary, and we can as well just
      use the decl we already have.  */
   else if (!TREE_ADDRESSABLE (decl)
+          && !TREE_THIS_VOLATILE (decl)
           && init
           && (fallback & fb_lvalue) == 0
           && gimple_test_f (init))
--- gcc/testsuite/gcc.dg/tree-ssa/pr89872.c     (nonexistent)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr89872.c     (revision 270023)
@@ -0,0 +1,27 @@
+/* PR c/89872 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " ={v} 1;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ={v} 2;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ={v} 3;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ={v} 4;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ={v} 0;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ={v} " 10 "optimized" } } */
+
+void
+foo (void)
+{
+  (volatile int){1} + (volatile int){2};
+}
+
+void
+bar (void)
+{
+  (volatile int){3};
+}
+
+void
+baz (void)
+{
+  (volatile int){4} / (volatile int){0};
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-03-29  Jakub Jelinek  <ja...@redhat.com>

        PR sanitizer/89869
        * typeck.c: Include gimplify.h.
        (cp_build_modify_expr) <case COND_EXPR>: Unshare rhs before using it
        for second time.  Formatting fixes.

        * g++.dg/ubsan/vptr-14.C: New test.

--- gcc/cp/typeck.c     (revision 270023)
+++ gcc/cp/typeck.c     (revision 270024)
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
+#include "gimplify.h"
 
 static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
 static tree cp_build_function_call (tree, tree, tsubst_flags_t);
@@ -8129,8 +8130,6 @@ cp_build_modify_expr (location_t loc, tr
        /* Produce (a ? (b = rhs) : (c = rhs))
           except that the RHS goes through a save-expr
           so the code to compute it is only emitted once.  */
-       tree cond;
-
        if (VOID_TYPE_P (TREE_TYPE (rhs)))
          {
            if (complain & tf_error)
@@ -8145,13 +8144,21 @@ cp_build_modify_expr (location_t loc, tr
        if (!lvalue_or_else (lhs, lv_assign, complain))
          return error_mark_node;
 
-       cond = build_conditional_expr
-         (input_location, TREE_OPERAND (lhs, 0),
-          cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
-                                modifycode, rhs, complain),
-          cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
-                                modifycode, rhs, complain),
-           complain);
+       tree op1 = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
+                                        modifycode, rhs, complain);
+       /* When sanitizing undefined behavior, even when rhs doesn't need
+          stabilization at this point, the sanitization might add extra
+          SAVE_EXPRs in there and so make sure there is no tree sharing
+          in the rhs, otherwise those SAVE_EXPRs will have initialization
+          only in one of the two branches.  */
+       if (sanitize_flags_p (SANITIZE_UNDEFINED
+                             | SANITIZE_UNDEFINED_NONDEFAULT))
+         rhs = unshare_expr (rhs);
+       tree op2 = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
+                                        modifycode, rhs, complain);
+       tree cond = build_conditional_expr (input_location,
+                                           TREE_OPERAND (lhs, 0), op1, op2,
+                                           complain);
 
        if (cond == error_mark_node)
          return cond;
--- gcc/testsuite/g++.dg/ubsan/vptr-14.C        (nonexistent)
+++ gcc/testsuite/g++.dg/ubsan/vptr-14.C        (revision 270024)
@@ -0,0 +1,18 @@
+// PR sanitizer/89869
+// { dg-do run }
+// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" }
+
+struct S { S *s = 0; virtual ~S () {} };
+
+void
+foo (S *x, S *y)
+{
+  (x->s ? y : x) = x->s;
+}
+
+int
+main ()
+{
+  S a;
+  foo (&a, 0);
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-09  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/89998
        * gimple-ssa-sprintf.c (try_substitute_return_value): Use lhs type
        instead of integer_type_node if possible, don't add ranges if return
        type is not compatible with int.
        * gimple-fold.c (gimple_fold_builtin_sprintf,
        gimple_fold_builtin_snprintf): Use lhs type instead of hardcoded
        integer_type_node.

        * gcc.c-torture/compile/pr89998-1.c: New test.
        * gcc.c-torture/compile/pr89998-2.c: New test.

--- gcc/gimple-ssa-sprintf.c    (revision 270223)
+++ gcc/gimple-ssa-sprintf.c    (revision 270224)
@@ -3692,10 +3692,10 @@ try_substitute_return_value (gimple_stmt
         are badly declared.  */
       && !stmt_ends_bb_p (info.callstmt))
     {
-      tree cst = build_int_cst (integer_type_node, retval[0]);
+      tree cst = build_int_cst (lhs ? TREE_TYPE (lhs) : integer_type_node,
+                               retval[0]);
 
-      if (lhs == NULL_TREE
-         && info.nowrite)
+      if (lhs == NULL_TREE && info.nowrite)
        {
          /* Remove the call to the bounded function with a zero size
             (e.g., snprintf(0, 0, "%i", 123)) if there is no lhs.  */
@@ -3736,7 +3736,7 @@ try_substitute_return_value (gimple_stmt
            }
        }
     }
-  else if (lhs)
+  else if (lhs && types_compatible_p (TREE_TYPE (lhs), integer_type_node))
     {
       bool setrange = false;
 
--- gcc/gimple-fold.c   (revision 270223)
+++ gcc/gimple-fold.c   (revision 270224)
@@ -3031,11 +3031,10 @@ gimple_fold_builtin_sprintf (gimple_stmt
       gimple_seq stmts = NULL;
       gimple *repl = gimple_build_call (fn, 2, dest, fmt);
       gimple_seq_add_stmt_without_update (&stmts, repl);
-      if (gimple_call_lhs (stmt))
+      if (tree lhs = gimple_call_lhs (stmt))
        {
-         repl = gimple_build_assign (gimple_call_lhs (stmt),
-                                     build_int_cst (integer_type_node,
-                                                    strlen (fmt_str)));
+         repl = gimple_build_assign (lhs, build_int_cst (TREE_TYPE (lhs),
+                                                         strlen (fmt_str)));
          gimple_seq_add_stmt_without_update (&stmts, repl);
          gsi_replace_with_seq_vops (gsi, stmts);
          /* gsi now points at the assignment to the lhs, get a
@@ -3079,12 +3078,12 @@ gimple_fold_builtin_sprintf (gimple_stmt
       gimple_seq stmts = NULL;
       gimple *repl = gimple_build_call (fn, 2, dest, orig);
       gimple_seq_add_stmt_without_update (&stmts, repl);
-      if (gimple_call_lhs (stmt))
+      if (tree lhs = gimple_call_lhs (stmt))
        {
-         if (!useless_type_conversion_p (integer_type_node,
+         if (!useless_type_conversion_p (TREE_TYPE (lhs),
                                          TREE_TYPE (orig_len)))
-           orig_len = fold_convert (integer_type_node, orig_len);
-         repl = gimple_build_assign (gimple_call_lhs (stmt), orig_len);
+           orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
+         repl = gimple_build_assign (lhs, orig_len);
          gimple_seq_add_stmt_without_update (&stmts, repl);
          gsi_replace_with_seq_vops (gsi, stmts);
          /* gsi now points at the assignment to the lhs, get a
@@ -3164,10 +3163,10 @@ gimple_fold_builtin_snprintf (gimple_stm
       gimple_seq stmts = NULL;
       gimple *repl = gimple_build_call (fn, 2, dest, fmt);
       gimple_seq_add_stmt_without_update (&stmts, repl);
-      if (gimple_call_lhs (stmt))
+      if (tree lhs = gimple_call_lhs (stmt))
        {
-         repl = gimple_build_assign (gimple_call_lhs (stmt),
-                                     build_int_cst (integer_type_node, len));
+         repl = gimple_build_assign (lhs,
+                                     build_int_cst (TREE_TYPE (lhs), len));
          gimple_seq_add_stmt_without_update (&stmts, repl);
          gsi_replace_with_seq_vops (gsi, stmts);
          /* gsi now points at the assignment to the lhs, get a
@@ -3216,12 +3215,12 @@ gimple_fold_builtin_snprintf (gimple_stm
       gimple_seq stmts = NULL;
       gimple *repl = gimple_build_call (fn, 2, dest, orig);
       gimple_seq_add_stmt_without_update (&stmts, repl);
-      if (gimple_call_lhs (stmt))
+      if (tree lhs = gimple_call_lhs (stmt))
        {
-         if (!useless_type_conversion_p (integer_type_node,
+         if (!useless_type_conversion_p (TREE_TYPE (lhs),
                                          TREE_TYPE (orig_len)))
-           orig_len = fold_convert (integer_type_node, orig_len);
-         repl = gimple_build_assign (gimple_call_lhs (stmt), orig_len);
+           orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
+         repl = gimple_build_assign (lhs, orig_len);
          gimple_seq_add_stmt_without_update (&stmts, repl);
          gsi_replace_with_seq_vops (gsi, stmts);
          /* gsi now points at the assignment to the lhs, get a
--- gcc/testsuite/gcc.c-torture/compile/pr89998-1.c     (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89998-1.c     (revision 270224)
@@ -0,0 +1,42 @@
+/* PR tree-optimization/89998 */
+
+unsigned int sprintf (char *str, const char *fmt, ...);
+unsigned int snprintf (char *str, __SIZE_TYPE__ len, const char *fmt, ...);
+
+int
+f1 (char *s)
+{
+  return sprintf (s, "foo");
+}
+
+int
+f2 (char *s)
+{
+  return sprintf (s, "%d", 123);
+}
+
+int
+f3 (int *p, char *s)
+{
+  const char *t = "bar";
+  return sprintf (s, "%s", t);
+}
+
+int
+f4 (char *s)
+{
+  return snprintf (s, 8, "foo");
+}
+
+int
+f5 (char *s)
+{
+  return snprintf (s, 8, "%d", 123);
+}
+
+int
+f6 (int *p, char *s)
+{
+  const char *t = "bar";
+  return snprintf (s, 8, "%s", t);
+}
--- gcc/testsuite/gcc.c-torture/compile/pr89998-2.c     (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr89998-2.c     (revision 270224)
@@ -0,0 +1,4 @@
+/* PR tree-optimization/89998 */
+/* { dg-additional-options "-fno-printf-return-value" } */
+
+#include "pr89998-1.c"
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        2019-04-10  Jakub Jelinek  <ja...@redhat.com>

        PR c++/90010
        * gimple-ssa-sprintf.c (target_to_host): Fix handling of targstr
        with strlen in between hostsz-3 and hostsz-1 inclusive when no
        translation is needed, and when translation is needed, only append
        ... if the string length is hostsz or more bytes long.  Avoid using
        strncpy or strcat.

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

--- gcc/gimple-ssa-sprintf.c    (revision 270245)
+++ gcc/gimple-ssa-sprintf.c    (revision 270246)
@@ -383,9 +383,14 @@ target_to_host (char *hostr, size_t host
      overlong strings just like the translated strings are.  */
   if (target_to_host_charmap['\0'] == 1)
     {
-      strncpy (hostr, targstr, hostsz - 4);
-      if (strlen (targstr) >= hostsz)
-       strcpy (hostr + hostsz - 4, "...");
+      size_t len = strlen (targstr);
+      if (len >= hostsz)
+       {
+         memcpy (hostr, targstr, hostsz - 4);
+         strcpy (hostr + hostsz - 4, "...");
+       }
+      else
+       memcpy (hostr, targstr, len + 1);
       return hostr;
     }
 
@@ -399,10 +404,9 @@ target_to_host (char *hostr, size_t host
       if (!*targstr)
        break;
 
-      if (size_t (ph - hostr) == hostsz - 4)
+      if (size_t (ph - hostr) == hostsz)
        {
-         *ph = '\0';
-         strcat (ph, "...");
+         strcpy (ph - 4, "...");
          break;
        }
     }
--- gcc/testsuite/gcc.dg/pr90010.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr90010.c      (revision 270246)
@@ -0,0 +1,27 @@
+/* PR c++/90010 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+char b[4096] = "abc";
+void bar (char *);
+
+void
+foo ()
+{
+  char d[4096];
+  __builtin_snprintf (d, sizeof d, "%sfoobarbazquxquuxquuzthudfred", b);       
/* { dg-warning "'foobarbazquxquuxquuzthudfred' directive output may be 
truncated writing 28 bytes into a region of size between 1 and 4096" } */
+  /* { dg-message "'__builtin_snprintf' output between 29 and 4124 bytes into 
a destination of size 4096" "" { target *-*-* } .-1 } */
+  bar (d);
+  __builtin_snprintf (d, sizeof d, "%sfoobarbazquxquuxquuzcorgefred", b);      
/* { dg-warning "'foobarbazquxquuxquuzcorgefred' directive output may be 
truncated writing 29 bytes into a region of size between 1 and 4096" } */
+  /* { dg-message "'__builtin_snprintf' output between 30 and 4125 bytes into 
a destination of size 4096" "" { target *-*-* } .-1 } */
+  bar (d);
+  __builtin_snprintf (d, sizeof d, "%sfoobarbazquxquuxquuzcorgewaldo", b);     
/* { dg-warning "'foobarbazquxquuxquuzcorgewaldo' directive output may be 
truncated writing 30 bytes into a region of size between 1 and 4096" } */
+  /* { dg-message "'__builtin_snprintf' output between 31 and 4126 bytes into 
a destination of size 4096" "" { target *-*-* } .-1 } */
+  bar (d);
+  __builtin_snprintf (d, sizeof d, "%sfoobarbazquxquuxquuzcorgegarply", b);    
/* { dg-warning "'foobarbazquxquuxquuzcorgegarply' directive output may be 
truncated writing 31 bytes into a region of size between 1 and 4096" } */
+  /* { dg-message "'__builtin_snprintf' output between 32 and 4127 bytes into 
a destination of size 4096" "" { target *-*-* } .-1 } */
+  bar (d);
+  __builtin_snprintf (d, sizeof d, "%sfoobarfredquxquuxquuzcorgegarply", b);   
/* { dg-warning "'foobarfredquxquuxquuzcorgega\.\.\.' directive output may be 
truncated writing 32 bytes into a region of size between 1 and 4096" } */
+  /* { dg-message "'__builtin_snprintf' output between 33 and 4128 bytes into 
a destination of size 4096" "" { target *-*-* } .-1 } */
+  bar (d);
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-11  Jakub Jelinek  <ja...@redhat.com>
        
        PR rtl-optimization/89965
        * dce.c (sp_based_mem_offset): New function.
        (find_call_stack_args): Use sp_based_mem_offset.

--- gcc/dce.c   (revision 270277)
+++ gcc/dce.c   (revision 270278)
@@ -272,6 +272,58 @@ check_argument_store (HOST_WIDE_INT size
   return true;
 }
 
+/* If MEM has sp address, return 0, if it has sp + const address,
+   return that const, if it has reg address where reg is set to sp + const
+   and FAST is false, return const, otherwise return
+   INTTYPE_MINUMUM (HOST_WIDE_INT).  */
+
+static HOST_WIDE_INT
+sp_based_mem_offset (rtx_call_insn *call_insn, const_rtx mem, bool fast)
+{
+  HOST_WIDE_INT off = 0;
+  rtx addr = XEXP (mem, 0);
+  if (GET_CODE (addr) == PLUS
+      && REG_P (XEXP (addr, 0))
+      && CONST_INT_P (XEXP (addr, 1)))
+    {
+      off = INTVAL (XEXP (addr, 1));
+      addr = XEXP (addr, 0);
+    }
+  if (addr == stack_pointer_rtx)
+    return off;
+
+  if (!REG_P (addr) || fast)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  /* If not fast, use chains to see if addr wasn't set to sp + offset.  */
+  df_ref use;
+  FOR_EACH_INSN_USE (use, call_insn)
+  if (rtx_equal_p (addr, DF_REF_REG (use)))
+    break;
+
+  if (use == NULL)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  struct df_link *defs;
+  for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
+    if (! DF_REF_IS_ARTIFICIAL (defs->ref))
+      break;
+
+  if (defs == NULL)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  rtx set = single_set (DF_REF_INSN (defs->ref));
+  if (!set)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  if (GET_CODE (SET_SRC (set)) != PLUS
+      || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
+      || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  off += INTVAL (XEXP (SET_SRC (set), 1));
+  return off;
+}
 
 /* Try to find all stack stores of CALL_INSN arguments if
    ACCUMULATE_OUTGOING_ARGS.  If all stack stores have been found
@@ -309,58 +361,13 @@ find_call_stack_args (rtx_call_insn *cal
     if (GET_CODE (XEXP (p, 0)) == USE
        && MEM_P (XEXP (XEXP (p, 0), 0)))
       {
-       rtx mem = XEXP (XEXP (p, 0), 0), addr;
-       HOST_WIDE_INT off = 0, size;
+       rtx mem = XEXP (XEXP (p, 0), 0);
+       HOST_WIDE_INT size;
        if (!MEM_SIZE_KNOWN_P (mem) || !MEM_SIZE (mem).is_constant (&size))
          return false;
-       addr = XEXP (mem, 0);
-       if (GET_CODE (addr) == PLUS
-           && REG_P (XEXP (addr, 0))
-           && CONST_INT_P (XEXP (addr, 1)))
-         {
-           off = INTVAL (XEXP (addr, 1));
-           addr = XEXP (addr, 0);
-         }
-       if (addr != stack_pointer_rtx)
-         {
-           if (!REG_P (addr))
-             return false;
-           /* If not fast, use chains to see if addr wasn't set to
-              sp + offset.  */
-           if (!fast)
-             {
-               df_ref use;
-               struct df_link *defs;
-               rtx set;
-
-               FOR_EACH_INSN_USE (use, call_insn)
-                 if (rtx_equal_p (addr, DF_REF_REG (use)))
-                   break;
-
-               if (use == NULL)
-                 return false;
-
-               for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
-                 if (! DF_REF_IS_ARTIFICIAL (defs->ref))
-                   break;
-
-               if (defs == NULL)
-                 return false;
-
-               set = single_set (DF_REF_INSN (defs->ref));
-               if (!set)
-                 return false;
-
-               if (GET_CODE (SET_SRC (set)) != PLUS
-                   || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
-                   || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
-                 return false;
-
-               off += INTVAL (XEXP (SET_SRC (set), 1));
-             }
-           else
-             return false;
-         }
+       HOST_WIDE_INT off = sp_based_mem_offset (call_insn, mem, fast);
+       if (off == INTTYPE_MINIMUM (HOST_WIDE_INT))
+         return false;
        min_sp_off = MIN (min_sp_off, off);
        max_sp_off = MAX (max_sp_off, off + size);
       }
@@ -376,40 +383,14 @@ find_call_stack_args (rtx_call_insn *cal
     if (GET_CODE (XEXP (p, 0)) == USE
        && MEM_P (XEXP (XEXP (p, 0), 0)))
       {
-       rtx mem = XEXP (XEXP (p, 0), 0), addr;
-       HOST_WIDE_INT off = 0, byte, size;
+       rtx mem = XEXP (XEXP (p, 0), 0);
        /* Checked in the previous iteration.  */
-       size = MEM_SIZE (mem).to_constant ();
-       addr = XEXP (mem, 0);
-       if (GET_CODE (addr) == PLUS
-           && REG_P (XEXP (addr, 0))
-           && CONST_INT_P (XEXP (addr, 1)))
-         {
-           off = INTVAL (XEXP (addr, 1));
-           addr = XEXP (addr, 0);
-         }
-       if (addr != stack_pointer_rtx)
-         {
-           df_ref use;
-           struct df_link *defs;
-           rtx set;
-
-           FOR_EACH_INSN_USE (use, call_insn)
-             if (rtx_equal_p (addr, DF_REF_REG (use)))
-               break;
-
-           for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
-             if (! DF_REF_IS_ARTIFICIAL (defs->ref))
-               break;
-
-           set = single_set (DF_REF_INSN (defs->ref));
-           off += INTVAL (XEXP (SET_SRC (set), 1));
-         }
-       for (byte = off; byte < off + size; byte++)
-         {
-           if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
-             gcc_unreachable ();
-         }
+       HOST_WIDE_INT size = MEM_SIZE (mem).to_constant ();
+       HOST_WIDE_INT off = sp_based_mem_offset (call_insn, mem, fast);
+       gcc_checking_assert (off != INTTYPE_MINIMUM (HOST_WIDE_INT));
+       for (HOST_WIDE_INT byte = off; byte < off + size; byte++)
+         if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
+           gcc_unreachable ();
       }
 
   /* Walk backwards, looking for argument stores.  The search stops
@@ -418,9 +399,6 @@ find_call_stack_args (rtx_call_insn *cal
   ret = false;
   for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
     {
-      rtx set, mem, addr;
-      HOST_WIDE_INT off;
-
       if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn)))
        prev_insn = NULL;
       else
@@ -432,61 +410,17 @@ find_call_stack_args (rtx_call_insn *cal
       if (!NONDEBUG_INSN_P (insn))
        continue;
 
-      set = single_set (insn);
+      rtx set = single_set (insn);
       if (!set || SET_DEST (set) == stack_pointer_rtx)
        break;
 
       if (!MEM_P (SET_DEST (set)))
        continue;
 
-      mem = SET_DEST (set);
-      addr = XEXP (mem, 0);
-      off = 0;
-      if (GET_CODE (addr) == PLUS
-         && REG_P (XEXP (addr, 0))
-         && CONST_INT_P (XEXP (addr, 1)))
-       {
-         off = INTVAL (XEXP (addr, 1));
-         addr = XEXP (addr, 0);
-       }
-      if (addr != stack_pointer_rtx)
-       {
-         if (!REG_P (addr))
-           break;
-         if (!fast)
-           {
-             df_ref use;
-             struct df_link *defs;
-             rtx set;
-
-             FOR_EACH_INSN_USE (use, insn)
-               if (rtx_equal_p (addr, DF_REF_REG (use)))
-                 break;
-
-             if (use == NULL)
-               break;
-
-             for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
-               if (! DF_REF_IS_ARTIFICIAL (defs->ref))
-                 break;
-
-             if (defs == NULL)
-               break;
-
-             set = single_set (DF_REF_INSN (defs->ref));
-             if (!set)
-               break;
-
-             if (GET_CODE (SET_SRC (set)) != PLUS
-                 || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
-                 || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
-               break;
-
-             off += INTVAL (XEXP (SET_SRC (set), 1));
-           }
-         else
-           break;
-       }
+      rtx mem = SET_DEST (set);
+      HOST_WIDE_INT off = sp_based_mem_offset (call_insn, mem, fast);
+      if (off == INTTYPE_MINIMUM (HOST_WIDE_INT))
+       break;
 
       HOST_WIDE_INT size;
       if (!MEM_SIZE_KNOWN_P (mem)
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-12  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/90026
        * cfgcleanup.c (try_optimize_cfg): When removing empty bb with no
        successors, look for BARRIERs inside of the whole BB_FOOTER chain
        rather than just at the start of it.  If e->src BB_FOOTER is not NULL
        in cfglayout mode, use emit_barrier_after_bb.

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

--- gcc/cfgcleanup.c    (revision 270303)
+++ gcc/cfgcleanup.c    (revision 270304)
@@ -2712,23 +2712,23 @@ try_optimize_cfg (int mode)
 
                      if (current_ir_type () == IR_RTL_CFGLAYOUT)
                        {
-                         if (BB_FOOTER (b)
-                             && BARRIER_P (BB_FOOTER (b)))
+                         rtx_insn *insn;
+                         for (insn = BB_FOOTER (b);
+                              insn; insn = NEXT_INSN (insn))
+                           if (BARRIER_P (insn))
+                             break;
+                         if (insn)
                            FOR_EACH_EDGE (e, ei, b->preds)
-                             if ((e->flags & EDGE_FALLTHRU)
-                                 && BB_FOOTER (e->src) == NULL)
+                             if ((e->flags & EDGE_FALLTHRU))
                                {
-                                 if (BB_FOOTER (b))
+                                 if (BB_FOOTER (b)
+                                     && BB_FOOTER (e->src) == NULL)
                                    {
                                      BB_FOOTER (e->src) = BB_FOOTER (b);
                                      BB_FOOTER (b) = NULL;
                                    }
                                  else
-                                   {
-                                     start_sequence ();
-                                     BB_FOOTER (e->src) = emit_barrier ();
-                                     end_sequence ();
-                                   }
+                                   emit_barrier_after_bb (e->src);
                                }
                        }
                      else
--- gcc/testsuite/g++.dg/opt/pr90026.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr90026.C  (revision 270304)
@@ -0,0 +1,24 @@
+// PR rtl-optimization/90026
+// { dg-do compile }
+// { dg-options "-fnon-call-exceptions -ftracer -O2 -w" }
+
+typedef __SIZE_TYPE__ size_t;
+struct S { int *b; ~S () { delete b; } };
+void bar ();
+char c[sizeof (int)];
+
+void *
+operator new (size_t, void *)
+{
+  __builtin_unreachable ();
+}
+
+void
+foo ()
+{
+  S a;
+  if (a.b)
+    a.b = new int ();
+  bar ();
+  new (c) int ();
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-12  Jakub Jelinek  <ja...@redhat.com>

        PR c/89946
        * varasm.c (assemble_start_function): Don't use tree_fits_uhwi_p
        and gcc_unreachable if it fails, just call tree_to_uhwi which
        verifies that too.  Test TREE_CHAIN instead of list_length > 1.
        Start warning message with a lower-case letter.  Formatting fixes.

        * c-attribs.c (handle_patchable_function_entry_attribute): Add
        function comment.  Warn if arguments of the attribute are not positive
        integer constants.

        * c-c++-common/pr89946.c: New test.

--- gcc/varasm.c        (revision 270304)
+++ gcc/varasm.c        (revision 270305)
@@ -1865,28 +1865,20 @@ assemble_start_function (tree decl, cons
       tree pp_val = TREE_VALUE (patchable_function_entry_attr);
       tree patchable_function_entry_value1 = TREE_VALUE (pp_val);
 
-      if (tree_fits_uhwi_p (patchable_function_entry_value1))
-       patch_area_size = tree_to_uhwi (patchable_function_entry_value1);
-      else
-       gcc_unreachable ();
-
+      patch_area_size = tree_to_uhwi (patchable_function_entry_value1);
       patch_area_entry = 0;
-      if (list_length (pp_val) > 1)
+      if (TREE_CHAIN (pp_val) != NULL_TREE)
        {
-         tree patchable_function_entry_value2 =
-           TREE_VALUE (TREE_CHAIN (pp_val));
-
-         if (tree_fits_uhwi_p (patchable_function_entry_value2))
-           patch_area_entry = tree_to_uhwi (patchable_function_entry_value2);
-         else
-           gcc_unreachable ();
+         tree patchable_function_entry_value2
+           = TREE_VALUE (TREE_CHAIN (pp_val));
+         patch_area_entry = tree_to_uhwi (patchable_function_entry_value2);
        }
     }
 
   if (patch_area_entry > patch_area_size)
     {
       if (patch_area_size > 0)
-       warning (OPT_Wattributes, "Patchable function entry > size");
+       warning (OPT_Wattributes, "patchable function entry > size");
       patch_area_entry = 0;
     }
 
@@ -1906,7 +1898,8 @@ assemble_start_function (tree decl, cons
   /* And the area after the label.  Record it if we haven't done so yet.  */
   if (patch_area_size > patch_area_entry)
     targetm.asm_out.print_patchable_function_entry (asm_out_file,
-                                            patch_area_size-patch_area_entry,
+                                                   patch_area_size
+                                                   - patch_area_entry,
                                                    patch_area_entry == 0);
 
   if (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (decl)))
--- gcc/c-family/c-attribs.c    (revision 270304)
+++ gcc/c-family/c-attribs.c    (revision 270305)
@@ -3562,9 +3562,28 @@ handle_fallthrough_attribute (tree *, tr
   return NULL_TREE;
 }
 
+/* Handle a "patchable_function_entry" attributes; arguments as in
+   struct attribute_spec.handler.  */
+
 static tree
-handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
+handle_patchable_function_entry_attribute (tree *, tree name, tree args,
+                                          int, bool *no_add_attrs)
 {
-  /* Nothing to be done here.  */
+  for (; args; args = TREE_CHAIN (args))
+    {
+      tree val = TREE_VALUE (args);
+      if (val && TREE_CODE (val) != IDENTIFIER_NODE
+         && TREE_CODE (val) != FUNCTION_DECL)
+       val = default_conversion (val);
+
+      if (!tree_fits_uhwi_p (val))
+       {
+         warning (OPT_Wattributes,
+                  "%qE attribute argument %qE is not an integer constant",
+                  name, val);
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+    }
   return NULL_TREE;
 }
--- gcc/testsuite/c-c++-common/pr89946.c        (nonexistent)
+++ gcc/testsuite/c-c++-common/pr89946.c        (revision 270305)
@@ -0,0 +1,7 @@
+/* PR c/89946 */
+
+__attribute__((patchable_function_entry (-1))) void foo (void) {}      /* { 
dg-warning "'patchable_function_entry' attribute argument '-1' is not an 
integer constant" } */
+__attribute__((patchable_function_entry (5, -5))) void bar (void) {}   /* { 
dg-warning "'patchable_function_entry' attribute argument '-5' is not an 
integer constant" } */
+int i, j;
+__attribute__((patchable_function_entry (i))) void baz (void) {}       /* { 
dg-warning "'patchable_function_entry' attribute argument 'i' is not an integer 
constant" } */
+__attribute__((patchable_function_entry (2, j))) void qux (void) {}    /* { 
dg-warning "'patchable_function_entry' attribute argument 'j' is not an integer 
constant" } */
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-12  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/89965
        * dce.c: Include rtl-iter.h.
        (struct check_argument_load_data): New type.
        (check_argument_load): New function.
        (find_call_stack_args): Check for loads from stack slots still tracked
        in sp_bytes and punt if any is found.

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

--- gcc/dce.c   (revision 270322)
+++ gcc/dce.c   (revision 270323)
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.
 #include "valtrack.h"
 #include "tree-pass.h"
 #include "dbgcnt.h"
+#include "rtl-iter.h"
 
 
 /* -------------------------------------------------------------------------
@@ -325,6 +326,48 @@ sp_based_mem_offset (rtx_call_insn *call
   return off;
 }
 
+/* Data for check_argument_load called via note_uses.  */
+struct check_argument_load_data {
+  bitmap sp_bytes;
+  HOST_WIDE_INT min_sp_off, max_sp_off;
+  rtx_call_insn *call_insn;
+  bool fast;
+  bool load_found;
+};
+
+/* Helper function for find_call_stack_args.  Check if there are
+   any loads from the argument slots in between the const/pure call
+   and store to the argument slot, set LOAD_FOUND if any is found.  */
+
+static void
+check_argument_load (rtx *loc, void *data)
+{
+  struct check_argument_load_data *d
+    = (struct check_argument_load_data *) data;
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, *loc, NONCONST)
+    {
+      const_rtx mem = *iter;
+      HOST_WIDE_INT size;
+      if (MEM_P (mem)
+         && MEM_SIZE_KNOWN_P (mem)
+         && MEM_SIZE (mem).is_constant (&size))
+       {
+         HOST_WIDE_INT off = sp_based_mem_offset (d->call_insn, mem, d->fast);
+         if (off != INTTYPE_MINIMUM (HOST_WIDE_INT)
+             && off < d->max_sp_off
+             && off + size > d->min_sp_off)
+           for (HOST_WIDE_INT byte = MAX (off, d->min_sp_off);
+                byte < MIN (off + size, d->max_sp_off); byte++)
+             if (bitmap_bit_p (d->sp_bytes, byte - d->min_sp_off))
+               {
+                 d->load_found = true;
+                 return;
+               }
+       }
+    }
+}
+
 /* Try to find all stack stores of CALL_INSN arguments if
    ACCUMULATE_OUTGOING_ARGS.  If all stack stores have been found
    and it is therefore safe to eliminate the call, return true,
@@ -394,8 +437,10 @@ find_call_stack_args (rtx_call_insn *cal
       }
 
   /* Walk backwards, looking for argument stores.  The search stops
-     when seeing another call, sp adjustment or memory store other than
-     argument store.  */
+     when seeing another call, sp adjustment, memory store other than
+     argument store or a read from an argument stack slot.  */
+  struct check_argument_load_data data
+    = { sp_bytes, min_sp_off, max_sp_off, call_insn, fast, false };
   ret = false;
   for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
     {
@@ -414,6 +459,10 @@ find_call_stack_args (rtx_call_insn *cal
       if (!set || SET_DEST (set) == stack_pointer_rtx)
        break;
 
+      note_uses (&PATTERN (insn), check_argument_load, &data);
+      if (data.load_found)
+       break;
+
       if (!MEM_P (SET_DEST (set)))
        continue;
 
--- gcc/testsuite/gcc.target/i386/pr89965.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr89965.c     (revision 270323)
@@ -0,0 +1,39 @@
+/* PR rtl-optimization/89965 */
+/* { dg-do run } */
+/* { dg-options "-O -mtune=nano-x2 -fcaller-saves -fexpensive-optimizations 
-fno-tree-dce -fno-tree-ter" } */
+/* { dg-additional-options "-march=i386" { target ia32 } } */
+
+int a;
+
+__attribute__ ((noipa)) unsigned long long
+foo (unsigned char c, unsigned d, unsigned e, unsigned long long f,
+     unsigned char g, unsigned h, unsigned long long i)
+{
+  (void) d;
+  unsigned short j = __builtin_mul_overflow_p (~0, h, c);
+  e <<= e;
+  i >>= 7;
+  c *= i;
+  i /= 12;
+  a = __builtin_popcount (c);
+  __builtin_add_overflow (e, a, &f);
+  return c + f + g + j + h;
+}
+
+__attribute__ ((noipa)) void
+bar (void)
+{
+  char buf[64];
+  __builtin_memset (buf, 0x55, sizeof buf);
+  asm volatile ("" : : "r" (&buf[0]) : "memory");
+}
+
+int
+main (void)
+{
+  bar ();
+  unsigned long long x = foo (2, 0, 0, 0, 0, 0, 0);
+  if (x != 0)
+    __builtin_abort ();
+  return 0;
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-12  Jakub Jelinek  <ja...@redhat.com>

        PR c/89933
        * c-decl.c (merge_decls): When newdecl's type is its main variant,
        don't try to remove it from the variant list, but instead assert
        it has no variants.

        * decl.c (duplicate_decls): When newdecl's type is its main variant,
        don't try to remove it from the variant list, but instead assert
        it has no variants.

        * c-c++-common/pr89933.c: New test.

--- gcc/c/c-decl.c      (revision 270328)
+++ gcc/c/c-decl.c      (revision 270329)
@@ -2512,13 +2512,16 @@ merge_decls (tree newdecl, tree olddecl,
       if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
        {
          tree remove = TREE_TYPE (newdecl);
-         for (tree t = TYPE_MAIN_VARIANT (remove); ;
-              t = TYPE_NEXT_VARIANT (t))
-           if (TYPE_NEXT_VARIANT (t) == remove)
-             {
-               TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
-               break;
-             }
+         if (TYPE_MAIN_VARIANT (remove) == remove)
+           gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+         else
+           for (tree t = TYPE_MAIN_VARIANT (remove); ;
+                t = TYPE_NEXT_VARIANT (t))
+             if (TYPE_NEXT_VARIANT (t) == remove)
+               {
+                 TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
+                 break;
+               }
        }
     }
 
--- gcc/cp/decl.c       (revision 270328)
+++ gcc/cp/decl.c       (revision 270329)
@@ -2132,13 +2132,16 @@ next_arg:;
          if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
            {
              tree remove = TREE_TYPE (newdecl);
-             for (tree t = TYPE_MAIN_VARIANT (remove); ;
-                  t = TYPE_NEXT_VARIANT (t))
-               if (TYPE_NEXT_VARIANT (t) == remove)
-                 {
-                   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
-                   break;
-                 }
+             if (TYPE_MAIN_VARIANT (remove) == remove)
+               gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+             else
+               for (tree t = TYPE_MAIN_VARIANT (remove); ;
+                    t = TYPE_NEXT_VARIANT (t))
+                 if (TYPE_NEXT_VARIANT (t) == remove)
+                   {
+                     TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
+                     break;
+                   }
            }
        }
       else if (merge_attr)
--- gcc/testsuite/c-c++-common/pr89933.c        (nonexistent)
+++ gcc/testsuite/c-c++-common/pr89933.c        (revision 270329)
@@ -0,0 +1,5 @@
+/* PR c/89933 */
+/* { dg-do compile } */
+
+typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__));
+typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__));
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-16  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/90090
        * tree-ssa-math-opts.c (is_division_by): Ignore divisions that can
        throw internally.
        (is_division_by_square): Likewise.  Formatting fix.

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

--- gcc/tree-ssa-math-opts.c    (revision 270378)
+++ gcc/tree-ssa-math-opts.c    (revision 270379)
@@ -334,7 +334,8 @@ is_division_by (gimple *use_stmt, tree d
         /* Do not recognize x / x as valid division, as we are getting
            confused later by replacing all immediate uses x in such
            a stmt.  */
-        && gimple_assign_rhs1 (use_stmt) != def;
+        && gimple_assign_rhs1 (use_stmt) != def
+        && !stmt_can_throw_internal (use_stmt);
 }
 
 /* Return whether USE_STMT is DEF * DEF.  */
@@ -359,13 +360,12 @@ is_division_by_square (gimple *use_stmt,
 {
   if (gimple_code (use_stmt) == GIMPLE_ASSIGN
       && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
-      && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt))
+      && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)
+      && !stmt_can_throw_internal (use_stmt))
     {
       tree denominator = gimple_assign_rhs2 (use_stmt);
       if (TREE_CODE (denominator) == SSA_NAME)
-       {
-         return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
-       }
+       return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
     }
   return 0;
 }
--- gcc/testsuite/g++.dg/opt/pr90090.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr90090.C  (revision 270379)
@@ -0,0 +1,19 @@
+// PR tree-optimization/90090
+// { dg-do compile }
+// { dg-options "-Ofast -fno-associative-math -fsignaling-nans -fno-tree-dce 
-fnon-call-exceptions" }
+
+double bar (double, double, double, double, double);
+double baz ();
+
+double
+foo (double a)
+{
+  try
+    {
+      return bar (1.0/a, 2.0/a, 4.0/a, 8.0/a, 16.0/a);
+    }
+  catch (...)
+    {
+      return baz ();
+    }
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-16  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/90082
        * dce.c (can_delete_call): New function.
        (deletable_insn_p, mark_insn): Use it.

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

--- gcc/dce.c   (revision 270379)
+++ gcc/dce.c   (revision 270380)
@@ -87,6 +87,32 @@ deletable_insn_p_1 (rtx body)
     }
 }
 
+/* Don't delete calls that may throw if we cannot do so.  */
+
+static bool
+can_delete_call (rtx_insn *insn)
+{
+  if (cfun->can_delete_dead_exceptions && can_alter_cfg)
+    return true;
+  if (!insn_nothrow_p (insn))
+    return false;
+  if (can_alter_cfg)
+    return true;
+  /* If we can't alter cfg, even when the call can't throw exceptions, it
+     might have EDGE_ABNORMAL_CALL edges and so we shouldn't delete such
+     calls.  */
+  gcc_assert (CALL_P (insn));
+  if (BLOCK_FOR_INSN (insn) && BB_END (BLOCK_FOR_INSN (insn)) == insn)
+    {
+      edge e;
+      edge_iterator ei;
+
+      FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs)
+       if ((e->flags & EDGE_ABNORMAL_CALL) != 0)
+         return false;
+    }
+  return true;
+}
 
 /* Return true if INSN is a normal instruction that can be deleted by
    the DCE pass.  */
@@ -111,8 +137,7 @@ deletable_insn_p (rtx_insn *insn, bool f
       && (RTL_CONST_OR_PURE_CALL_P (insn)
          && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
       /* Don't delete calls that may throw if we cannot do so.  */
-      && ((cfun->can_delete_dead_exceptions && can_alter_cfg)
-         || insn_nothrow_p (insn)))
+      && can_delete_call (insn))
     return find_call_stack_args (as_a <rtx_call_insn *> (insn), false,
                                 fast, arg_stores);
 
@@ -206,8 +231,7 @@ mark_insn (rtx_insn *insn, bool fast)
          && !SIBLING_CALL_P (insn)
          && (RTL_CONST_OR_PURE_CALL_P (insn)
              && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
-         && ((cfun->can_delete_dead_exceptions && can_alter_cfg)
-             || insn_nothrow_p (insn)))
+         && can_delete_call (insn))
        find_call_stack_args (as_a <rtx_call_insn *> (insn), true, fast, NULL);
     }
 }
--- gcc/testsuite/gcc.dg/pr90082.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr90082.c      (revision 270380)
@@ -0,0 +1,13 @@
+/* PR rtl-optimization/90082 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fnon-call-exceptions -ftrapv" } */
+
+void *buf[5];
+
+void
+foo (int a)
+{
+  if (__builtin_setjmp (buf) == 0)
+    __asm__ ("" : : "n" (a * 2));      /* { dg-error "impossible constraint in 
'asm'" } */
+                                       /* { dg-warning "asm operand 0 probably 
doesn't match constraints" "" { target *-*-* } .-1 } */
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-19  Jakub Jelinek  <ja...@redhat.com>

        PR c++/90108
        * c-decl.c (merge_decls): If remove is main variant and
        DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE
        variant that has newdecl as TYPE_NAME if any.

        * decl.c (duplicate_decls): If remove is main variant and
        DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE
        variant that has newdecl as TYPE_NAME if any.

        * c-c++-common/pr90108.c: New test.

--- gcc/c/c-decl.c      (revision 270452)
+++ gcc/c/c-decl.c      (revision 270453)
@@ -2513,7 +2513,24 @@ merge_decls (tree newdecl, tree olddecl,
        {
          tree remove = TREE_TYPE (newdecl);
          if (TYPE_MAIN_VARIANT (remove) == remove)
-           gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+           {
+             gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+             /* If remove is the main variant, no need to remove that
+                from the list.  One of the DECL_ORIGINAL_TYPE
+                variants, e.g. created for aligned attribute, might still
+                refer to the newdecl TYPE_DECL though, so remove that one
+                in that case.  */
+             if (DECL_ORIGINAL_TYPE (newdecl)
+                 && DECL_ORIGINAL_TYPE (newdecl) != remove)
+               for (tree t = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (newdecl));
+                    t; t = TYPE_MAIN_VARIANT (t))
+                 if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl)
+                   {
+                     TYPE_NEXT_VARIANT (t)
+                       = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t));
+                     break;
+                   }
+           }       
          else
            for (tree t = TYPE_MAIN_VARIANT (remove); ;
                 t = TYPE_NEXT_VARIANT (t))
--- gcc/cp/decl.c       (revision 270452)
+++ gcc/cp/decl.c       (revision 270453)
@@ -2133,7 +2133,24 @@ next_arg:;
            {
              tree remove = TREE_TYPE (newdecl);
              if (TYPE_MAIN_VARIANT (remove) == remove)
-               gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+               {
+                 gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+                 /* If remove is the main variant, no need to remove that
+                    from the list.  One of the DECL_ORIGINAL_TYPE
+                    variants, e.g. created for aligned attribute, might still
+                    refer to the newdecl TYPE_DECL though, so remove that one
+                    in that case.  */
+                 if (tree orig = DECL_ORIGINAL_TYPE (newdecl))
+                   if (orig != remove)
+                     for (tree t = TYPE_MAIN_VARIANT (orig); t;
+                          t = TYPE_MAIN_VARIANT (t))
+                       if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl)
+                         {
+                           TYPE_NEXT_VARIANT (t)
+                             = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t));
+                           break;
+                         }
+               }           
              else
                for (tree t = TYPE_MAIN_VARIANT (remove); ;
                     t = TYPE_NEXT_VARIANT (t))
--- gcc/testsuite/c-c++-common/pr90108.c        (nonexistent)
+++ gcc/testsuite/c-c++-common/pr90108.c        (revision 270453)
@@ -0,0 +1,6 @@
+/* PR c++/90108 */
+/* { dg-do compile } */
+/* { dg-options "--param ggc-min-heapsize=0" } */
+
+typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__));
+typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__));
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-24  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/90208
        * tree-cfg.c (remove_bb): Move forced labels from removed bbs
        after labels of new_bb, not before them.

        * gcc.dg/tsan/pr90208-2.c: New test.

--- gcc/tree-cfg.c      (revision 270533)
+++ gcc/tree-cfg.c      (revision 270534)
@@ -2265,7 +2265,7 @@ remove_bb (basic_block bb)
                  new_bb = single_succ (new_bb);
                  gcc_assert (new_bb != bb);
                }
-             new_gsi = gsi_start_bb (new_bb);
+             new_gsi = gsi_after_labels (new_bb);
              gsi_remove (&i, false);
              gsi_insert_before (&new_gsi, stmt, GSI_NEW_STMT);
            }
--- gcc/testsuite/gcc.dg/tsan/pr90208-2.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/tsan/pr90208-2.c       (revision 270534)
@@ -0,0 +1,20 @@
+/* PR tree-optimization/90208 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fexceptions -fsanitize=thread" } */
+
+void *b[5];
+void foo (void);
+
+void
+bar (int d)
+{
+  while (d)
+    foo ();
+}
+
+void
+baz (void)
+{
+  bar (2);
+  __builtin_setjmp (b);
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-24  Jakub Jelinek  <ja...@redhat.com>

        PR target/90187
        * config/i386/i386.c (ix86_expand_sse_fp_minmax): Force if_true into
        a register if both if_true and if_false are MEMs.

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

--- gcc/config/i386/i386.c      (revision 270536)
+++ gcc/config/i386/i386.c      (revision 270537)
@@ -23712,6 +23712,8 @@ ix86_expand_sse_fp_minmax (rtx dest, enu
   else
     {
       code = is_min ? SMIN : SMAX;
+      if (MEM_P (if_true) && MEM_P (if_false))
+       if_true = force_reg (mode, if_true);
       tmp = gen_rtx_fmt_ee (code, mode, if_true, if_false);
     }
 
--- gcc/testsuite/g++.dg/opt/pr90187.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr90187.C  (revision 270537)
@@ -0,0 +1,15 @@
+// PR target/90187
+// { dg-do compile }
+// { dg-options "-Ofast -ffloat-store" }
+
+double a[64];
+double *foo (void);
+
+void
+bar (int x, const double *y)
+{
+  int i;
+  for (i = 0; i < x; i++)
+    if (y[i] < a[i])
+      a[i] = y[i];
+}
2019-04-30  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-04-24  Jakub Jelinek  <ja...@redhat.com>

        PR target/90193
        * rtl.c (classify_insn): Return JUMP_INSN for asm goto.
        * emit-rtl.c (try_split): Copy over REG_LABEL_TARGET.

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

--- gcc/emit-rtl.c      (revision 270549)
+++ gcc/emit-rtl.c      (revision 270550)
@@ -3940,6 +3940,7 @@ try_split (rtx pat, rtx_insn *trial, int
          break;
 
        case REG_NON_LOCAL_GOTO:
+       case REG_LABEL_TARGET:
          for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
            {
              if (JUMP_P (insn))
--- gcc/rtl.c   (revision 270549)
+++ gcc/rtl.c   (revision 270550)
@@ -746,6 +746,8 @@ classify_insn (rtx x)
     return CALL_INSN;
   if (ANY_RETURN_P (x))
     return JUMP_INSN;
+  if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_VEC (x))
+    return JUMP_INSN;
   if (GET_CODE (x) == SET)
     {
       if (GET_CODE (SET_DEST (x)) == PC)
@@ -772,6 +774,9 @@ classify_insn (rtx x)
          return CALL_INSN;
       if (has_return_p)
        return JUMP_INSN;
+      if (GET_CODE (XVECEXP (x, 0, 0)) == ASM_OPERANDS
+         && ASM_OPERANDS_LABEL_VEC (XVECEXP (x, 0, 0)))
+       return JUMP_INSN;
     }
 #ifdef GENERATOR_FILE
   if (GET_CODE (x) == MATCH_OPERAND
--- gcc/testsuite/gcc.target/i386/pr90193.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr90193.c     (revision 270550)
@@ -0,0 +1,21 @@
+/* PR target/90193 *
+/* { dg-do link } */
+/* { dg-options "-O1" } */
+/* { dg-require-effective-target tls } */
+
+__thread int var;
+
+static int
+foo (void)
+{
+  asm goto ("jmp %l[l]\n\t" : : "m" (var) : : l);
+  return 0;
+l:
+  return 1;
+}
+
+int
+main ()
+{
+  return foo ();
+}

Reply via email to