Hi! I've backported 75 commits from 7.x branch to 6.x, bootstrapped/regtested them on x86_64-linux and i686-linux and committed to gcc-6-branch.
Jakub
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-09-27 Jakub Jelinek <ja...@redhat.com> PR c++/82159 * gimplify.c (gimplify_modify_expr): Don't optimize away zero sized lhs from calls if the lhs has addressable type. * g++.dg/opt/pr82159.C: New test. --- gcc/gimplify.c (revision 253317) +++ gcc/gimplify.c (revision 253318) @@ -5434,7 +5434,12 @@ gimplify_modify_expr (tree *expr_p, gimp side as statements and throw away the assignment. Do this after gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable types properly. */ - if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value) + if (zero_sized_type (TREE_TYPE (*from_p)) + && !want_value + /* Don't do this for calls that return addressable types, expand_call + relies on those having a lhs. */ + && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p)) + && TREE_CODE (*from_p) == CALL_EXPR)) { gimplify_stmt (from_p, pre_p); gimplify_stmt (to_p, pre_p); --- gcc/testsuite/g++.dg/opt/pr82159.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr82159.C (revision 253318) @@ -0,0 +1,18 @@ +// PR c++/82159 +// { dg-do compile } +// { dg-options "" } + +template<int N> +struct S +{ + ~S () {} + template<int M> S<M> foo () { return S<M> (); } + unsigned char data[N]; +}; + +int +main () +{ + S<16> d; + S<0> t = d.foo<0> (); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-09-29 Jakub Jelinek <ja...@redhat.com> PR c/82340 * c-decl.c (build_compound_literal): Use c_apply_type_quals_to_decl instead of trying to set just TREE_READONLY manually. * gcc.dg/tree-ssa/pr82340.c: New test. --- gcc/c/c-decl.c (revision 253318) +++ gcc/c/c-decl.c (revision 253319) @@ -5092,9 +5092,7 @@ build_compound_literal (location_t loc, TREE_USED (decl) = 1; DECL_READ_P (decl) = 1; TREE_TYPE (decl) = type; - TREE_READONLY (decl) = (TYPE_READONLY (type) - || (TREE_CODE (type) == ARRAY_TYPE - && TYPE_READONLY (TREE_TYPE (type)))); + c_apply_type_quals_to_decl (TYPE_QUALS (strip_array_types (type)), decl); store_init_value (loc, decl, init, NULL_TREE); if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) --- gcc/testsuite/gcc.dg/tree-ssa/pr82340.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/pr82340.c (revision 253319) @@ -0,0 +1,14 @@ +/* PR c/82340 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ssa" } */ +/* { dg-final { scan-tree-dump "D.\[0-9]*\\\[0\\\] ={v} 77;" "ssa" } } */ + +int +foo (void) +{ + int i; + volatile char *p = (volatile char[1]) { 77 }; + for (i = 1; i < 10; i++) + *p = 4; + return *p; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-09-15 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/82192 * combine.c (make_extraction): Don't look through non-paradoxical SUBREGs or TRUNCATE if pos + len is or might be bigger than inner's mode. * gcc.c-torture/execute/pr82192.c: New test. --- gcc/combine.c (revision 254176) +++ gcc/combine.c (revision 254177) @@ -7397,7 +7397,14 @@ make_extraction (machine_mode mode, rtx if (pos_rtx && CONST_INT_P (pos_rtx)) pos = INTVAL (pos_rtx), pos_rtx = 0; - if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) + if (GET_CODE (inner) == SUBREG + && subreg_lowpart_p (inner) + && (paradoxical_subreg_p (inner) + /* If trying or potentionally trying to extract + bits outside of is_mode, don't look through + non-paradoxical SUBREGs. See PR82192. */ + || (pos_rtx == NULL_RTX + && pos + len <= GET_MODE_PRECISION (is_mode)))) { /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), consider just the QI as the memory to extract from. @@ -7423,7 +7430,12 @@ make_extraction (machine_mode mode, rtx if (new_rtx != 0) return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1)); } - else if (GET_CODE (inner) == TRUNCATE) + else if (GET_CODE (inner) == TRUNCATE + /* If trying or potentionally trying to extract + bits outside of is_mode, don't look through + TRUNCATE. See PR82192. */ + && pos_rtx == NULL_RTX + && pos + len <= GET_MODE_PRECISION (is_mode)) inner = XEXP (inner, 0); inner_mode = GET_MODE (inner); --- gcc/testsuite/gcc.c-torture/execute/pr82192.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr82192.c (revision 254177) @@ -0,0 +1,22 @@ +/* PR rtl-optimization/82192 */ + +unsigned long long int a = 0x95dd3d896f7422e2ULL; +struct S { unsigned int m : 13; } b; + +__attribute__((noinline, noclone)) void +foo (void) +{ + b.m = ((unsigned) a) >> (0x644eee9667723bf7LL + | a & ~0xdee27af8U) - 0x644eee9667763bd8LL; +} + +int +main () +{ + if (__INT_MAX__ != 0x7fffffffULL) + return 0; + foo (); + if (b.m != 0) + __builtin_abort (); + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-10-12 Jakub Jelinek <ja...@redhat.com> PR c++/82159 * expr.c (store_field): Don't optimize away bitsize == 0 store from CALL_EXPR with addressable return type. * g++.dg/opt/pr82159-2.C: New test. --- gcc/expr.c (revision 254180) +++ gcc/expr.c (revision 254181) @@ -6742,8 +6742,11 @@ store_field (rtx target, HOST_WIDE_INT b return const0_rtx; /* If we have nothing to store, do nothing unless the expression has - side-effects. */ - if (bitsize == 0) + side-effects. Don't do that for zero sized addressable lhs of + calls. */ + if (bitsize == 0 + && (!TREE_ADDRESSABLE (TREE_TYPE (exp)) + || TREE_CODE (exp) != CALL_EXPR)) return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL); if (GET_CODE (target) == CONCAT) --- gcc/testsuite/g++.dg/opt/pr82159-2.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr82159-2.C (revision 254181) @@ -0,0 +1,65 @@ +// PR c++/82159 +// { dg-do compile } +// { dg-options "" } + +template <typename T> struct D { T e; }; +struct F : D<int[0]> { + F(const F &); +}; +struct G : F { + template <class T> G operator-(T); +}; +template <class T> struct I { + typedef typename T::template J<I> ak; +}; +template <class T> struct K { typename I<T>::ak an; }; +struct H { + G l; +}; +struct C { + ~C(); +}; +template <class T> struct M : T { + template <typename U, typename V> M(U, V); + H h; + virtual void foo() { T::bar(&h); } +}; +template <int, typename> class A; +template <class> struct B { + typedef int BT; + struct BC {}; + template <class T> struct BD { + G g; + BD(BT, T n) : g(n.l - 0) {} + }; + B(BT, BC); +}; +template <typename> struct O; +template <int T, typename U> +struct O<B<A<T, U> > > : public B<A<T, U> >::BC {}; +struct L : B<A<2, double> > { + struct P : C { + void bar(H *x) { + BT a; + BD<H>(a, *x); + } + }; + template <typename U, typename V> L(U x, V n) : B(x, n) {} + int ll; + virtual int baz() { M<P>(this, ll); } +}; +template <typename> class Q { + O<B<A<2, double> > > q; + virtual L baz() { L(0, q); } +}; +template <template <class> class T> struct R { + R() { T<int>(); } +}; +struct S { + template <class> class J : R<Q> {}; +}; +void foo() { K<S> c; } + +int main() { + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-20 Jakub Jelinek <ja...@redhat.com> PR c++/82781 * constexpr.c (cxx_eval_vector_conditional_expression): New function. (cxx_eval_constant_expression) <case VEC_COND_EXPR>: Use it instead of cxx_eval_conditional_expression. * g++.dg/ext/constexpr-pr82781.C: New test. --- gcc/cp/constexpr.c (revision 255706) +++ gcc/cp/constexpr.c (revision 255707) @@ -2044,6 +2044,45 @@ cxx_eval_conditional_expression (const c jump_target); } +/* Subroutine of cxx_eval_constant_expression. + Attempt to evaluate vector condition expressions. Unlike + cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal + ternary arithmetics operation, where all 3 arguments have to be + evaluated as constants and then folding computes the result from + them. */ + +static tree +cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t, + bool *non_constant_p, bool *overflow_p) +{ + tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), + /*lval*/false, + non_constant_p, overflow_p); + VERIFY_CONSTANT (arg1); + tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), + /*lval*/false, + non_constant_p, overflow_p); + VERIFY_CONSTANT (arg2); + tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2), + /*lval*/false, + non_constant_p, overflow_p); + VERIFY_CONSTANT (arg3); + location_t loc = EXPR_LOCATION (t); + tree type = TREE_TYPE (t); + tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3); + if (r == NULL_TREE) + { + if (arg1 == TREE_OPERAND (t, 0) + && arg2 == TREE_OPERAND (t, 1) + && arg3 == TREE_OPERAND (t, 2)) + r = t; + else + r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3); + } + VERIFY_CONSTANT (r); + return r; +} + /* Returns less than, equal to, or greater than zero if KEY is found to be less than, to match, or to be greater than the constructor_elt's INDEX. */ @@ -4361,12 +4400,14 @@ cxx_eval_constant_expression (const cons jump_target); break; } - /* FALLTHRU */ - case VEC_COND_EXPR: r = cxx_eval_conditional_expression (ctx, t, lval, non_constant_p, overflow_p, jump_target); break; + case VEC_COND_EXPR: + r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p, + overflow_p); + break; case CONSTRUCTOR: if (TREE_CONSTANT (t)) --- gcc/testsuite/g++.dg/ext/constexpr-pr82781.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/constexpr-pr82781.C (revision 255707) @@ -0,0 +1,12 @@ +// PR c++/82781 +// { dg-do compile { target c++11 } } + +typedef int V __attribute__ ((vector_size (16))); +constexpr V b1 = { 0, 1, 10, 20 }; +constexpr V b2 = { 0, 2, 10, 0 }; +constexpr V b3 = b1 == b2; + +static_assert (b3[0] == -1, ""); +static_assert (b3[1] == 0, ""); +static_assert (b3[2] == -1, ""); +static_assert (b3[3] == 0, "");
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-21 Jakub Jelinek <ja...@redhat.com> PR c++/83059 * c-common.c (get_atomic_generic_size): Use TREE_INT_CST_LOW instead of tree_to_uhwi, formatting fix. * c-c++-common/pr83059.c: New test. --- gcc/c-family/c-common.c (revision 255707) +++ gcc/c-family/c-common.c (revision 255708) @@ -6823,13 +6823,14 @@ get_atomic_generic_size (location_t loc, tree p = (*params)[x]; if (TREE_CODE (p) == INTEGER_CST) { - int i = tree_to_uhwi (p); - if (i < 0 || (memmodel_base (i) >= MEMMODEL_LAST)) - { - warning_at (loc, OPT_Winvalid_memory_model, - "invalid memory model argument %d of %qE", x + 1, - function); - } + /* memmodel_base masks the low 16 bits, thus ignore any bits above + it by using TREE_INT_CST_LOW instead of tree_to_*hwi. Those high + bits will be checked later during expansion in target specific + way. */ + if (memmodel_base (TREE_INT_CST_LOW (p)) >= MEMMODEL_LAST) + warning_at (loc, OPT_Winvalid_memory_model, + "invalid memory model argument %d of %qE", x + 1, + function); } else if (!INTEGRAL_TYPE_P (TREE_TYPE (p))) --- gcc/testsuite/c-c++-common/pr83059.c (nonexistent) +++ gcc/testsuite/c-c++-common/pr83059.c (revision 255708) @@ -0,0 +1,10 @@ +/* PR c++/83059 */ +/* { dg-do compile } */ + +void +foo (int *p, int *q, int *r) +{ + __atomic_compare_exchange (p, q, r, 0, 0, -1); /* { dg-warning "invalid memory model argument 6" } */ + /* { dg-warning "\[uU]nknown architecture specifi" "" { target *-*-* } .-1 } */ + /* { dg-warning "failure memory model cannot be stronger than success memory model" "" { target *-*-* } .-2 } */ +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-21 James Cowgill <james.cowg...@imgtec.com> Jakub Jelinek <ja...@redhat.com> PR target/82880 * config/mips/frame-header-opt.c (mips_register_frame_header_opt): Remove static keyword from f variable. * gcc.dg/opts-8.c: New test. --- gcc/config/mips/frame-header-opt.c (revision 255708) +++ gcc/config/mips/frame-header-opt.c (revision 255709) @@ -98,8 +98,7 @@ void mips_register_frame_header_opt (void) { opt_pass *p = make_pass_ipa_frame_header_opt (g); - static struct register_pass_info f = - {p, "comdats", 1, PASS_POS_INSERT_AFTER }; + struct register_pass_info f = { p, "comdats", 1, PASS_POS_INSERT_AFTER }; register_pass (&f); } --- gcc/testsuite/gcc.dg/opts-8.c (nonexistent) +++ gcc/testsuite/gcc.dg/opts-8.c (revision 255709) @@ -0,0 +1,6 @@ +/* PR target/82880 */ +/* Test we don't ICE or hang. */ +/* { dg-do compile } */ +/* { dg-options "--help=target --help=optimizers" } */ +/* { dg-allow-blank-lines-in-output 1 } */ +/* { dg-prune-output ".*" } */
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-23 Jakub Jelinek <ja...@redhat.com> PR middle-end/82253 * expr.c (expand_assignment): For CONCAT to_rtx, complex type from and bitpos/bitsize covering the whole destination, use store_expr only if the complex mode is the same. Otherwise, use expand_normal and if it returns CONCAT, subreg each part separately instead of trying to subreg the whole result. * gfortran.dg/pr82253.f90: New test. --- gcc/expr.c (revision 255710) +++ gcc/expr.c (revision 255711) @@ -5104,7 +5104,8 @@ expand_assignment (tree to, tree from, b else if (GET_CODE (to_rtx) == CONCAT) { unsigned short mode_bitsize = GET_MODE_BITSIZE (GET_MODE (to_rtx)); - if (COMPLEX_MODE_P (TYPE_MODE (TREE_TYPE (from))) + if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE (to_rtx) + && COMPLEX_MODE_P (GET_MODE (to_rtx)) && bitpos == 0 && bitsize == mode_bitsize) result = store_expr (from, to_rtx, false, nontemporal, reversep); @@ -5125,14 +5126,30 @@ expand_assignment (tree to, tree from, b nontemporal, reversep); else if (bitpos == 0 && bitsize == mode_bitsize) { - rtx from_rtx; result = expand_normal (from); - from_rtx = simplify_gen_subreg (GET_MODE (to_rtx), result, - TYPE_MODE (TREE_TYPE (from)), 0); - emit_move_insn (XEXP (to_rtx, 0), - read_complex_part (from_rtx, false)); - emit_move_insn (XEXP (to_rtx, 1), - read_complex_part (from_rtx, true)); + if (GET_CODE (result) == CONCAT) + { + machine_mode to_mode = GET_MODE_INNER (GET_MODE (to_rtx)); + machine_mode from_mode = GET_MODE_INNER (GET_MODE (result)); + rtx from_real + = simplify_gen_subreg (to_mode, XEXP (result, 0), + from_mode, 0); + rtx from_imag + = simplify_gen_subreg (to_mode, XEXP (result, 1), + from_mode, 1); + emit_move_insn (XEXP (to_rtx, 0), from_real); + emit_move_insn (XEXP (to_rtx, 1), from_imag); + } + else + { + rtx from_rtx + = simplify_gen_subreg (GET_MODE (to_rtx), result, + TYPE_MODE (TREE_TYPE (from)), 0); + emit_move_insn (XEXP (to_rtx, 0), + read_complex_part (from_rtx, false)); + emit_move_insn (XEXP (to_rtx, 1), + read_complex_part (from_rtx, true)); + } } else { --- gcc/testsuite/gfortran.dg/pr82253.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/pr82253.f90 (revision 255711) @@ -0,0 +1,40 @@ +! PR middle-end/82253 +! { dg-do compile { target fortran_real_16 } } +! { dg-options "-Og" } + +module pr82253 + implicit none + private + public :: static_type + type, public :: T + procedure(), nopass, pointer :: testProc => null() + end type + type, public :: S + complex(kind=16), pointer :: ptr + end type + type(T), target :: type_complex32 + interface static_type + module procedure foo + end interface + interface + subroutine bar (testProc) + procedure(), optional :: testProc + end subroutine + end interface + contains + function foo (self) result(res) + complex(kind=16) :: self + type(T), pointer :: res + call bar (testProc = baz) + end function + subroutine baz (buffer, status) + character(len=*) :: buffer + integer(kind=4) :: status + complex(kind=16), target :: obj + type(S) :: self + integer(kind=1), parameter :: zero(storage_size(obj)/8) = 0 + obj = transfer (zero, obj) + self%ptr => obj + write (buffer, *, iostat=status) self%ptr, '#' + end subroutine +end module pr82253
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-23 Dirk Broemmel <d.broem...@fz-juelich.de> Jakub Jelinek <ja...@redhat.com> PR fortran/81841 * parse.c (parse_spec): Allow ST_OMP_THREADPRIVATE inside of BLOCK DATA. * libgomp.fortran/pr81841.f90: New test. --- gcc/fortran/parse.c (revision 255711) +++ gcc/fortran/parse.c (revision 255712) @@ -3694,6 +3694,7 @@ loop: case ST_EQUIVALENCE: case ST_IMPLICIT: case ST_IMPLICIT_NONE: + case ST_OMP_THREADPRIVATE: case ST_PARAMETER: case ST_STRUCTURE_DECL: case ST_TYPE: --- libgomp/testsuite/libgomp.fortran/pr81841.f90 (nonexistent) +++ libgomp/testsuite/libgomp.fortran/pr81841.f90 (revision 255712) @@ -0,0 +1,26 @@ +! PR fortran/81841 +! { dg-do run } + +block data + integer :: a + real :: b(2) + common /c/ a, b + !$omp threadprivate (/c/) + data a / 32 / + data b /2*1./ +end + +program pr81841 + use omp_lib + integer :: e + real :: f(2) + common /c/ e, f + !$omp threadprivate (/c/) + !$omp parallel num_threads(8) + if ((e /= 32) .or. any(f /= 1.)) call abort + e = omp_get_thread_num () + f = e + 19. + !$omp barrier + if ((e /= omp_get_thread_num ()) .or. any(f /= e + 19.)) call abort + !$omp end parallel +end
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-23 Jakub Jelinek <ja...@redhat.com> * parser.c (cp_parser_omp_declare): Change return type to bool from void, return true for declare simd. (cp_parser_pragma): Return cp_parser_omp_declare returned value rather than always false. --- gcc/cp/parser.c (revision 255712) +++ gcc/cp/parser.c (revision 255713) @@ -36357,7 +36357,7 @@ cp_parser_omp_declare_reduction (cp_pars initializer-clause[opt] new-line #pragma omp declare target new-line */ -static void +static bool cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok, enum pragma_context context) { @@ -36371,7 +36371,7 @@ cp_parser_omp_declare (cp_parser *parser cp_lexer_consume_token (parser->lexer); cp_parser_omp_declare_simd (parser, pragma_tok, context); - return; + return true; } cp_ensure_no_omp_declare_simd (parser); if (strcmp (p, "reduction") == 0) @@ -36379,23 +36379,24 @@ cp_parser_omp_declare (cp_parser *parser cp_lexer_consume_token (parser->lexer); cp_parser_omp_declare_reduction (parser, pragma_tok, context); - return; + return false; } if (!flag_openmp) /* flag_openmp_simd */ { cp_parser_skip_to_pragma_eol (parser, pragma_tok); - return; + return false; } if (strcmp (p, "target") == 0) { cp_lexer_consume_token (parser->lexer); cp_parser_omp_declare_target (parser, pragma_tok); - return; + return false; } } cp_parser_error (parser, "expected %<simd%> or %<reduction%> " "or %<target%>"); cp_parser_require_pragma_eol (parser, pragma_tok); + return false; } /* OpenMP 4.5: @@ -37370,8 +37371,7 @@ cp_parser_pragma (cp_parser *parser, enu return false; case PRAGMA_OMP_DECLARE_REDUCTION: - cp_parser_omp_declare (parser, pragma_tok, context); - return false; + return cp_parser_omp_declare (parser, pragma_tok, context); case PRAGMA_OACC_DECLARE: cp_parser_oacc_declare (parser, pragma_tok);
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-24 Jakub Jelinek <ja...@redhat.com> * tree-object-size.c (pass_through_call): Do not handle BUILT_IN_STPNCPY_CHK which is not a pass through call. * gcc.dg/builtin-object-size-18.c: New test. --- gcc/tree-object-size.c (revision 255713) +++ gcc/tree-object-size.c (revision 255714) @@ -481,7 +481,6 @@ pass_through_call (const gcall *call) case BUILT_IN_MEMSET_CHK: case BUILT_IN_STRCPY_CHK: case BUILT_IN_STRNCPY_CHK: - case BUILT_IN_STPNCPY_CHK: case BUILT_IN_STRCAT_CHK: case BUILT_IN_STRNCAT_CHK: case BUILT_IN_ASSUME_ALIGNED: --- gcc/testsuite/gcc.dg/builtin-object-size-18.c (nonexistent) +++ gcc/testsuite/gcc.dg/builtin-object-size-18.c (revision 255714) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* __stpncpy_chk could return buf up to buf + 64, so + the minimum object size might be far smaller than 64. */ +/* { dg-final { scan-tree-dump-not "return 64;" "optimized" } } */ + +typedef __SIZE_TYPE__ size_t; + +size_t +foo (const char *p, size_t s, size_t t) +{ + char buf[64]; + char *q = __builtin___stpncpy_chk (buf, p, s, t); + return __builtin_object_size (q, 2); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-24 Jakub Jelinek <ja...@redhat.com> PR sanitizer/83014 * ubsan.c (ubsan_type_descriptor): Use pp_unsigned_wide_integer instead of pp_printf with HOST_WIDE_INT_PRINT_DEC. Avoid calling tree_to_uhwi twice. * gcc.dg/ubsan/pr83014.c: New test. --- gcc/ubsan.c (revision 255714) +++ gcc/ubsan.c (revision 255715) @@ -433,10 +433,10 @@ ubsan_type_descriptor (tree type, enum u && TYPE_MAX_VALUE (dom) != NULL_TREE && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST) { + unsigned HOST_WIDE_INT m; if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom)) - && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0) - pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC, - tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1); + && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0) + pp_unsigned_wide_integer (&pretty_name, m + 1); else pp_wide_int (&pretty_name, wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1), --- gcc/testsuite/gcc.dg/ubsan/pr83014.c (nonexistent) +++ gcc/testsuite/gcc.dg/ubsan/pr83014.c (revision 255715) @@ -0,0 +1,12 @@ +/* PR sanitizer/83014 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined" } */ + +int +foo (void) +{ + int data[5]; + data[0] = 0; + data[5] = 0; + return data[0]; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-24 Jakub Jelinek <ja...@redhat.com> PR fortran/81304 * trans-openmp.c (gfc_trans_omp_array_reduction_or_udr): Set attr.implicit_type in intrinsic_sym to avoid undesirable warning. * testsuite/libgomp.fortran/pr81304.f90: New test. --- gcc/fortran/trans-openmp.c (revision 255715) +++ gcc/fortran/trans-openmp.c (revision 255716) @@ -1623,6 +1623,7 @@ gfc_trans_omp_array_reduction_or_udr (tr intrinsic_sym.attr.referenced = 1; intrinsic_sym.attr.intrinsic = 1; intrinsic_sym.attr.function = 1; + intrinsic_sym.attr.implicit_type = 1; intrinsic_sym.result = &intrinsic_sym; intrinsic_sym.declared_at = where; --- libgomp/testsuite/libgomp.fortran/pr81304.f90 (nonexistent) +++ libgomp/testsuite/libgomp.fortran/pr81304.f90 (revision 255716) @@ -0,0 +1,17 @@ +! PR fortran/81304 +! { dg-do run } +! { dg-options "-Wsurprising" } + +program pr81304 + integer :: i + real, dimension(1:3) :: a, b, c + a = 128 + b = 0 +!$omp parallel do reduction(min: a) reduction(max: b) private (c) ! { dg-bogus "Type specified for intrinsic function" } + do i = 1, 16 + c = (/ i, i - 5, i + 5 /) + a = min (a, c) + b = max (b, c) + end do + if (any (a /= (/ 1, -4, 6 /)) .or. any (b /= (/ 16, 11, 21 /))) call abort +end
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-11-29 Jakub Jelinek <ja...@redhat.com> PR target/80819 * config/i386/sse.md (vec_concatv2di): Remove * from (=Yr,0,*rm) alternative. * gcc.target/i386/pr80819-1.c: New test. * gcc.target/i386/pr80819-2.c: New test. --- gcc/config/i386/sse.md (revision 255719) +++ gcc/config/i386/sse.md (revision 255720) @@ -13616,7 +13616,7 @@ (match_operand:DI 1 "nonimmediate_operand" " 0, 0,x ,r ,xm,?!*Yn,0,x,0,0,x") (match_operand:DI 2 "vector_move_operand" - "*rm,rm,rm,C ,C ,C ,x,x,x,m,m")))] + " rm,rm,rm,C ,C ,C ,x,x,x,m,m")))] "TARGET_SSE" "@ pinsrq\t{$1, %2, %0|%0, %2, 1} --- gcc/testsuite/gcc.target/i386/pr80819-1.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr80819-1.c (revision 255720) @@ -0,0 +1,13 @@ +/* PR target/80819 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse4 -mno-avx -mtune=haswell -masm=att" } */ + +typedef unsigned long long V __attribute__((vector_size (16))); + +V +foo (unsigned long long x, unsigned long long y) +{ + return (V) { x, y }; +} + +/* { dg-final { scan-assembler-not "movq\[ \t]*%rsi, \[-0-9]*\\(" } } */ --- gcc/testsuite/gcc.target/i386/pr80819-2.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr80819-2.c (revision 255720) @@ -0,0 +1,13 @@ +/* PR target/80819 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse4 -mno-avx -mtune=generic -masm=att" } */ + +typedef unsigned long long V __attribute__((vector_size (16))); + +V +foo (unsigned long long x, unsigned long long y) +{ + return (V) { x, y }; +} + +/* { dg-final { scan-assembler-not "movq\[ \t]*%rsi, \[-0-9]*\\(" } } */
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-02 Jakub Jelinek <ja...@redhat.com> PR target/78643 PR target/80583 * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield is BLKmode for vector field with vector raw mode, use TYPE_MODE instead of DECL_MODE. * gcc.target/i386/pr80583.c: New test. --- gcc/expr.c (revision 255720) +++ gcc/expr.c (revision 255721) @@ -7015,7 +7015,16 @@ get_inner_reference (tree exp, HOST_WIDE size. */ mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field)); else if (!DECL_BIT_FIELD (field)) - mode = DECL_MODE (field); + { + mode = DECL_MODE (field); + /* For vector fields re-check the target flags, as DECL_MODE + could have been set with different target flags than + the current function has. */ + if (mode == BLKmode + && VECTOR_TYPE_P (TREE_TYPE (field)) + && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field)))) + mode = TYPE_MODE (TREE_TYPE (field)); + } else if (DECL_MODE (field) == BLKmode) blkmode_bitfield = true; --- gcc/testsuite/gcc.target/i386/pr80583.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr80583.c (revision 255721) @@ -0,0 +1,13 @@ +/* PR target/80583 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mno-avx" } */ + +typedef int V __attribute__((__vector_size__(32))); +struct S { V a; }; + +V __attribute__((target ("avx"))) +foo (struct S *b) +{ + V x = b->a; + return x; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-02 Jakub Jelinek <ja...@redhat.com> PR c++/81212 * tree-cfg.c (pass_warn_function_return::execute): Handle __builtin_ubsan_handle_missing_return like __builtin_unreachable with BUILTINS_LOCATION. * g++.dg/ubsan/pr81212.C: New test. --- gcc/tree-cfg.c (revision 255721) +++ gcc/tree-cfg.c (revision 255722) @@ -8917,7 +8917,6 @@ pass_warn_function_return::execute (func without returning a value. */ else if (warn_return_type && !TREE_NO_WARNING (fun->decl) - && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0 && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl)))) { FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) @@ -8931,11 +8930,40 @@ pass_warn_function_return::execute (func location = gimple_location (last); if (location == UNKNOWN_LOCATION) location = fun->function_end_locus; - warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function"); + warning_at (location, OPT_Wreturn_type, + "control reaches end of non-void function"); TREE_NO_WARNING (fun->decl) = 1; break; } } + /* -fsanitize=return turns fallthrough from the end of non-void function + into __builtin___ubsan_handle_missing_return () call. + Recognize those too. */ + basic_block bb; + if (!TREE_NO_WARNING (fun->decl) && (flag_sanitize & SANITIZE_RETURN)) + FOR_EACH_BB_FN (bb, fun) + if (EDGE_COUNT (bb->succs) == 0) + { + gimple *last = last_stmt (bb); + const enum built_in_function ubsan_missing_ret + = BUILT_IN_UBSAN_HANDLE_MISSING_RETURN; + if (last && gimple_call_builtin_p (last, ubsan_missing_ret)) + { + gimple_stmt_iterator gsi = gsi_for_stmt (last); + gsi_prev_nondebug (&gsi); + gimple *prev = gsi_stmt (gsi); + if (prev == NULL) + location = UNKNOWN_LOCATION; + else + location = gimple_location (prev); + if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION) + location = fun->function_end_locus; + warning_at (location, OPT_Wreturn_type, + "control reaches end of non-void function"); + TREE_NO_WARNING (fun->decl) = 1; + break; + } + } } return 0; } --- gcc/testsuite/g++.dg/ubsan/pr81212.C (nonexistent) +++ gcc/testsuite/g++.dg/ubsan/pr81212.C (revision 255722) @@ -0,0 +1,16 @@ +// PR c++/81212 +// { dg-do compile } +// { dg-options "-Wreturn-type -fsanitize=return" } + +struct S +{ + S (void *); + void *s; +}; + +S +foo (bool x, void *y) +{ + if (x) + return S (y); +} // { dg-warning "control reaches end of non-void function" }
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-06 Jakub Jelinek <ja...@redhat.com> PR c++/80259 * decl2.c (grokfield): Diagnose = delete redefinition of a friend. * g++.dg/cpp0x/pr80259.C: New test. --- gcc/cp/decl2.c (revision 255722) +++ gcc/cp/decl2.c (revision 255723) @@ -888,9 +888,18 @@ grokfield (const cp_declarator *declarat { if (init == ridpointers[(int)RID_DELETE]) { - DECL_DELETED_FN (value) = 1; - DECL_DECLARED_INLINE_P (value) = 1; - DECL_INITIAL (value) = error_mark_node; + if (friendp && decl_defined_p (value)) + { + error ("redefinition of %q#D", value); + inform (DECL_SOURCE_LOCATION (value), + "%q#D previously defined here", value); + } + else + { + DECL_DELETED_FN (value) = 1; + DECL_DECLARED_INLINE_P (value) = 1; + DECL_INITIAL (value) = error_mark_node; + } } else if (init == ridpointers[(int)RID_DEFAULT]) { --- gcc/testsuite/g++.dg/cpp0x/pr80259.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/pr80259.C (revision 255723) @@ -0,0 +1,13 @@ +// PR c++/80259 +// { dg-do compile { target c++11 } } + +void foo () {} // { dg-message "previously defined here" } +void bar (); + +struct A +{ + friend void foo () = delete; // { dg-error "redefinition of" } + friend void bar () = delete; // { dg-message "previously defined here" } +}; + +void bar () {} // { dg-error "redefinition of" }
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-08 Joseph Myers <jos...@codesourcery.com> Alexander Monakov <amona...@ispras.ru> Jakub Jelinek <ja...@redhat.com> PR target/81906 * config/i386/i386.c (ix86_expand_rint): Handle flag_rounding_math. * gcc.target/i386/pr81906.c: New test. --- gcc/config/i386/i386.c (revision 255724) +++ gcc/config/i386/i386.c (revision 255725) @@ -45299,8 +45299,7 @@ ix86_expand_lfloorceil (rtx op0, rtx op1 emit_move_insn (op0, ireg); } -/* Expand rint (IEEE round to nearest) rounding OPERAND1 and storing the - result in OPERAND0. */ +/* Expand rint rounding OPERAND1 and storing the result in OPERAND0. */ void ix86_expand_rint (rtx operand0, rtx operand1) { @@ -45308,11 +45307,17 @@ ix86_expand_rint (rtx operand0, rtx oper xa = fabs (operand1); if (!isless (xa, 2**52)) return operand1; - xa = xa + 2**52 - 2**52; + two52 = 2**52; + if (flag_rounding_math) + { + two52 = copysign (two52, operand1); + xa = operand1; + } + xa = xa + two52 - two52; return copysign (xa, operand1); */ machine_mode mode = GET_MODE (operand0); - rtx res, xa, TWO52, mask; + rtx res, xa, TWO52, two52, mask; rtx_code_label *label; res = gen_reg_rtx (mode); @@ -45325,8 +45330,16 @@ ix86_expand_rint (rtx operand0, rtx oper TWO52 = ix86_gen_TWO52 (mode); label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false); - xa = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT); - xa = expand_simple_binop (mode, MINUS, xa, TWO52, xa, 0, OPTAB_DIRECT); + two52 = TWO52; + if (flag_rounding_math) + { + two52 = gen_reg_rtx (mode); + ix86_sse_copysign_to_positive (two52, TWO52, res, mask); + xa = res; + } + + xa = expand_simple_binop (mode, PLUS, xa, two52, NULL_RTX, 0, OPTAB_DIRECT); + xa = expand_simple_binop (mode, MINUS, xa, two52, xa, 0, OPTAB_DIRECT); ix86_sse_copysign_to_positive (res, xa, res, mask); --- gcc/testsuite/gcc.target/i386/pr81906.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr81906.c (revision 255725) @@ -0,0 +1,37 @@ +/* PR target/81906 */ +/* { dg-do run { target *-*-linux* *-*-gnu* } } +/* { dg-options "-O2 -frounding-math" } */ + +#include <fenv.h> + +int +main () +{ + #define N 12 + double a[N] = { 2.0, 2.25, 2.5, 2.75, 3.5, -2.0, -2.25, -2.5, -2.75, -3.5, 0x2.0p53, -0x2.0p53 }; + double b[N], c[N], d[N], e[N]; + double be[N] = { 2.0, 2.0, 2.0, 3.0, 4.0, -2.0, -2.0, -2.0, -3.0, -4.0, 0x2.0p53, -0x2.0p53 }; + double ce[N] = { 2.0, 2.0, 2.0, 2.0, 3.0, -2.0, -3.0, -3.0, -3.0, -4.0, 0x2.0p53, -0x2.0p53 }; + double de[N] = { 2.0, 3.0, 3.0, 3.0, 4.0, -2.0, -2.0, -2.0, -2.0, -3.0, 0x2.0p53, -0x2.0p53 }; + double ee[N] = { 2.0, 2.0, 2.0, 2.0, 3.0, -2.0, -2.0, -2.0, -2.0, -3.0, 0x2.0p53, -0x2.0p53 }; + asm volatile ("" : : "g" (a), "g" (be), "g" (ce), "g" (de), "g" (ee) : "memory"); + + int i; + fesetround (FE_TONEAREST); + for (i = 0; i < N; ++i) + b[i] = __builtin_rint (a[i]); + fesetround (FE_DOWNWARD); + for (i = 0; i < N; ++i) + c[i] = __builtin_rint (a[i]); + fesetround (FE_UPWARD); + for (i = 0; i < N; ++i) + d[i] = __builtin_rint (a[i]); + fesetround (FE_TOWARDZERO); + for (i = 0; i < N; ++i) + e[i] = __builtin_rint (a[i]); + fesetround (FE_TONEAREST); + for (i = 0; i < N; ++i) + if (b[i] != be[i] || c[i] != ce[i] || d[i] != de[i] || e[i] != ee[i]) + __builtin_abort (); + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-14 Jakub Jelinek <ja...@redhat.com> PR c++/79650 * pt.c (convert_nontype_argument): Diagnose reduced_constant_expression_p expressions that aren't INTEGER_CST. * g++.dg/template/pr79650.C: New test. --- gcc/cp/pt.c (revision 255726) +++ gcc/cp/pt.c (revision 255727) @@ -6523,7 +6523,20 @@ convert_nontype_argument (tree type, tre return NULL_TREE; /* else cxx_constant_value complained but gave us a real constant, so go ahead. */ - gcc_assert (TREE_CODE (expr) == INTEGER_CST); + if (TREE_CODE (expr) != INTEGER_CST) + { + /* Some assemble time constant expressions like + (intptr_t)&&lab1 - (intptr_t)&&lab2 or + 4 + (intptr_t)&&var satisfy reduced_constant_expression_p + as we can emit them into .rodata initializers of + variables, yet they can't fold into an INTEGER_CST at + compile time. Refuse them here. */ + gcc_checking_assert (reduced_constant_expression_p (expr)); + location_t loc = EXPR_LOC_OR_LOC (expr, input_location); + error_at (loc, "template argument %qE for type %qT not " + "a constant integer", expr, type); + return NULL_TREE; + } } else return NULL_TREE; --- gcc/testsuite/g++.dg/template/pr79650.C (nonexistent) +++ gcc/testsuite/g++.dg/template/pr79650.C (revision 255727) @@ -0,0 +1,20 @@ +// PR c++/79650 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +typedef __INTPTR_TYPE__ intptr_t; +template<intptr_t> struct A {}; + +void +foo () +{ + static int a, b; +lab1: +lab2: + A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c; // { dg-error "not a constant integer" } + A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d; + A<(intptr_t)&a - (intptr_t)&b> e; // { dg-error "is not a constant expression" } + A<(intptr_t)&a - (intptr_t)&a> f; + A<(intptr_t)sizeof(a) + (intptr_t)&a> g; // { dg-error "not a constant integer" } + A<(intptr_t)&a> h; // { dg-error "conversion from pointer type" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-19 Jakub Jelinek <ja...@redhat.com> PR ipa/82801 PR ipa/83346 * ipa-inline.c (flatten_remove_node_hook): New function. (ipa_inline): Keep only nodes with flatten attribute at the end of the array in the order from ipa_reverse_postorder, only walk that portion of array for flattening, if there is more than one such node, temporarily register a removal hook and ignore removed nodes. * g++.dg/ipa/pr82801.C: New test. --- gcc/ipa-inline.c (revision 255967) +++ gcc/ipa-inline.c (revision 255968) @@ -2358,6 +2358,19 @@ dump_inline_stats (void) (int) reason[i][2], (int) reason[i][1], reason[i][0]); } +/* Called when node is removed. */ + +static void +flatten_remove_node_hook (struct cgraph_node *node, void *data) +{ + if (lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) == NULL) + return; + + hash_set<struct cgraph_node *> *removed + = (hash_set<struct cgraph_node *> *) data; + removed->add (node); +} + /* Decide on the inlining. We do so in the topological order to avoid expenses on updating data structures. */ @@ -2367,7 +2380,7 @@ ipa_inline (void) struct cgraph_node *node; int nnodes; struct cgraph_node **order; - int i; + int i, j; int cold; bool remove_functions = false; @@ -2408,26 +2421,56 @@ ipa_inline (void) if (dump_file) fprintf (dump_file, "\nFlattening functions:\n"); + /* First shrink order array, so that it only contains nodes with + flatten attribute. */ + for (i = nnodes - 1, j = i; i >= 0; i--) + { + node = order[i]; + if (lookup_attribute ("flatten", + DECL_ATTRIBUTES (node->decl)) != NULL) + order[j--] = order[i]; + } + + /* After the above loop, order[j + 1] ... order[nnodes - 1] contain + nodes with flatten attribute. If there is more than one such + node, we need to register a node removal hook, as flatten_function + could remove other nodes with flatten attribute. See PR82801. */ + struct cgraph_node_hook_list *node_removal_hook_holder = NULL; + hash_set<struct cgraph_node *> *flatten_removed_nodes = NULL; + if (j < nnodes - 2) + { + flatten_removed_nodes = new hash_set<struct cgraph_node *>; + node_removal_hook_holder + = symtab->add_cgraph_removal_hook (&flatten_remove_node_hook, + flatten_removed_nodes); + } + /* In the first pass handle functions to be flattened. Do this with a priority so none of our later choices will make this impossible. */ - for (i = nnodes - 1; i >= 0; i--) + for (i = nnodes - 1; i > j; i--) { node = order[i]; + if (flatten_removed_nodes + && flatten_removed_nodes->contains (node)) + continue; /* Handle nodes to be flattened. Ideally when processing callees we stop inlining at the entry of cycles, possibly cloning that entry point and try to flatten itself turning it into a self-recursive function. */ - if (lookup_attribute ("flatten", - DECL_ATTRIBUTES (node->decl)) != NULL) - { - if (dump_file) - fprintf (dump_file, - "Flattening %s\n", node->name ()); - flatten_function (node, false); - } + if (dump_file) + fprintf (dump_file, "Flattening %s\n", node->name ()); + flatten_function (node, false); } + + if (j < nnodes - 2) + { + symtab->remove_cgraph_removal_hook (node_removal_hook_holder); + delete flatten_removed_nodes; + } + free (order); + if (dump_file) dump_overall_stats (); @@ -2439,7 +2482,6 @@ ipa_inline (void) inline functions and virtual functions so we really know what is called once. */ symtab->remove_unreachable_nodes (dump_file); - free (order); /* Inline functions with a property that after inlining into all callers the code size will shrink because the out-of-line copy is eliminated. --- gcc/testsuite/g++.dg/ipa/pr82801.C (nonexistent) +++ gcc/testsuite/g++.dg/ipa/pr82801.C (revision 255968) @@ -0,0 +1,20 @@ +// PR ipa/82801 +// { dg-do compile } +// { dg-options "-O2 -Wno-attributes" } + +template<int> +struct A { A () {} }; +struct B { double foo () const; }; + +__attribute__((always_inline, flatten)) +double B::foo () const +{ + A<1> v; + return 0.0; +} + +int +main () +{ + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-21 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/83521 * tree-ssa-phiopt.c (factor_out_conditional_conversion): Use gimple_build_assign without code on result of fold_build1 (VIEW_CONVERT_EXPR, ...), as it might not create a VIEW_CONVERT_EXPR. * gcc.dg/pr83521.c: New test. --- gcc/tree-ssa-phiopt.c (revision 255968) +++ gcc/tree-ssa-phiopt.c (revision 255969) @@ -523,8 +523,12 @@ factor_out_conditional_conversion (edge /* Create the conversion stmt and insert it. */ if (convert_code == VIEW_CONVERT_EXPR) - temp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (result), temp); - new_stmt = gimple_build_assign (result, convert_code, temp); + { + temp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (result), temp); + new_stmt = gimple_build_assign (result, temp); + } + else + new_stmt = gimple_build_assign (result, convert_code, temp); gsi = gsi_after_labels (gimple_bb (phi)); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); --- gcc/testsuite/gcc.dg/pr83521.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83521.c (revision 255969) @@ -0,0 +1,10 @@ +/* PR tree-optimization/83521 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-tree-forwprop" } */ + +int +foo (unsigned int x, int y) +{ + int *z = (int *)&x; + return (y == 0) ? y : *z; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-21 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/83523 * tree-ssa-math-opts.c (is_widening_mult_p): Return false if for INTEGER_TYPE TYPE_OVERFLOW_TRAPS. (convert_mult_to_fma): Likewise. * g++.dg/tree-ssa/pr83523.C: New test. --- gcc/tree-ssa-math-opts.c (revision 255969) +++ gcc/tree-ssa-math-opts.c (revision 255970) @@ -3074,8 +3074,12 @@ is_widening_mult_p (gimple *stmt, { tree type = TREE_TYPE (gimple_assign_lhs (stmt)); - if (TREE_CODE (type) != INTEGER_TYPE - && TREE_CODE (type) != FIXED_POINT_TYPE) + if (TREE_CODE (type) == INTEGER_TYPE) + { + if (TYPE_OVERFLOW_TRAPS (type)) + return false; + } + else if (TREE_CODE (type) != FIXED_POINT_TYPE) return false; if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out, @@ -3443,7 +3447,8 @@ convert_mult_to_fma (gimple *mul_stmt, t /* We don't want to do bitfield reduction ops. */ if (INTEGRAL_TYPE_P (type) && (TYPE_PRECISION (type) - != GET_MODE_PRECISION (TYPE_MODE (type)))) + != GET_MODE_PRECISION (TYPE_MODE (type)) + || TYPE_OVERFLOW_TRAPS (type))) return false; /* If the target doesn't support it, don't generate it. We assume that --- gcc/testsuite/g++.dg/tree-ssa/pr83523.C (nonexistent) +++ gcc/testsuite/g++.dg/tree-ssa/pr83523.C (revision 255970) @@ -0,0 +1,25 @@ +// PR tree-optimization/83523 +// { dg-do compile } +// { dg-options "-O2 -fexceptions -fnon-call-exceptions -ftrapv" } + +#ifdef __SIZEOF_INT128__ +typedef __int128 T; +typedef long long int U; +#else +typedef long long int T; +typedef int U; +#endif + +struct S { S (); ~S (); }; +void bar (); + +T +foo (U x, U y) +{ + T z = x; + S s; + bar (); + z *= y; + bar (); + return z; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-21 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/80747 PR rtl-optimization/83512 * cfgrtl.c (force_nonfallthru_and_redirect): When splitting succ edge from ENTRY, copy partition from e->dest to the newly created bb. * bb-reorder.c (reorder_basic_blocks_simple): If last_tail is ENTRY, use BB_PARTITION of its successor block as current_partition. Don't copy partition when splitting succ edge from ENTRY. * gcc.dg/pr80747.c: New test. * gcc.dg/pr83512.c: New test. --- gcc/bb-reorder.c (revision 255970) +++ gcc/bb-reorder.c (revision 255971) @@ -2405,7 +2405,10 @@ reorder_basic_blocks_simple (void) basic_block last_tail = (basic_block) ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux; - int current_partition = BB_PARTITION (last_tail); + int current_partition + = BB_PARTITION (last_tail == ENTRY_BLOCK_PTR_FOR_FN (cfun) + ? EDGE_SUCC (ENTRY_BLOCK_PTR_FOR_FN (cfun), 0)->dest + : last_tail); bool need_another_pass = true; for (int pass = 0; pass < 2 && need_another_pass; pass++) @@ -2446,7 +2449,6 @@ reorder_basic_blocks_simple (void) { force_nonfallthru (e); e->src->aux = ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux; - BB_COPY_PARTITION (e->src, e->dest); } } --- gcc/cfgrtl.c (revision 255970) +++ gcc/cfgrtl.c (revision 255971) @@ -1542,6 +1542,9 @@ force_nonfallthru_and_redirect (edge e, basic_block bb = create_basic_block (BB_HEAD (e->dest), NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun)); + /* Make sure new block ends up in correct hot/cold section. */ + BB_COPY_PARTITION (bb, e->dest); + /* Change the existing edge's source to be the new block, and add a new edge from the entry block to the new block. */ e->src = bb; --- gcc/testsuite/gcc.dg/pr83512.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83512.c (revision 255971) @@ -0,0 +1,16 @@ +/* PR rtl-optimization/83512 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -freorder-blocks-algorithm=simple" } */ + +int a; + +void +foo (int *x) +{ + for (;;) + { + for (*x = 0; *x < 1; *x++) + ; + ++a; + } +} --- gcc/testsuite/gcc.dg/pr80747.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr80747.c (revision 255971) @@ -0,0 +1,18 @@ +/* PR rtl-optimization/80747 */ +/* { dg-do compile } */ +/* { dg-options "-fprofile-use -freorder-blocks-and-partition -O1 -foptimize-sibling-calls" } */ + +int +foo (int a) +{ + int r; + if (a & 1) + r = foo (a - 1); + else if (a) + r = foo (a - 2); + else + return 0; + if (r) + r = r; + return r; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-22 Jakub Jelinek <ja...@redhat.com> PR debug/83550 * c-decl.c (finish_struct): Set DECL_SOURCE_LOCATION on TYPE_STUB_DECL and call rest_of_type_compilation before processing incomplete vars rather than after it. * c-c++-common/dwarf2/pr83550.c: New test. --- gcc/c/c-decl.c (revision 255981) +++ gcc/c/c-decl.c (revision 255982) @@ -8123,6 +8123,14 @@ finish_struct (location_t loc, tree t, t warning_at (loc, 0, "union cannot be made transparent"); } + /* Update type location to the one of the definition, instead of e.g. + a forward declaration. */ + if (TYPE_STUB_DECL (t)) + DECL_SOURCE_LOCATION (TYPE_STUB_DECL (t)) = loc; + + /* Finish debugging output for this type. */ + rest_of_type_compilation (t, toplevel); + /* If this structure or union completes the type of any previous variable declaration, lay it out and output its rtl. */ for (x = incomplete_vars; x; x = TREE_CHAIN (x)) @@ -8139,14 +8147,6 @@ finish_struct (location_t loc, tree t, t } } - /* Update type location to the one of the definition, instead of e.g. - a forward declaration. */ - if (TYPE_STUB_DECL (t)) - DECL_SOURCE_LOCATION (TYPE_STUB_DECL (t)) = loc; - - /* Finish debugging output for this type. */ - rest_of_type_compilation (t, toplevel); - /* If we're inside a function proper, i.e. not file-scope and not still parsing parameters, then arrange for the size of a variable sized type to be bound now. */ --- gcc/testsuite/c-c++-common/dwarf2/pr83550.c (nonexistent) +++ gcc/testsuite/c-c++-common/dwarf2/pr83550.c (revision 255982) @@ -0,0 +1,10 @@ +/* PR debug/83550 */ +/* { dg-do compile } */ +/* { dg-options "-gdwarf -dA -fno-merge-debug-strings" } */ + +struct my_struct; +extern struct my_struct s; +struct my_struct { int a, b; }; +struct my_struct q; + +/* { dg-final { scan-assembler "DW_TAG_structure_type\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"my_struct\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0x)?7\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-12-23 Jakub Jelinek <ja...@redhat.com> PR c++/83553 * fold-const.c (struct contains_label_data): New type. (contains_label_1): Return non-NULL even for CASE_LABEL_EXPR, unless inside of a SWITCH_BODY seen during the walk. (contains_label_p): Use walk_tree instead of walk_tree_without_duplicates, prepare data for contains_label_1 and provide own pset. * c-c++-common/torture/pr83553.c: New test. --- gcc/fold-const.c (revision 255987) +++ gcc/fold-const.c (revision 255988) @@ -11536,22 +11536,48 @@ fold_binary_loc (location_t loc, enum tr } /* switch (code) */ } +/* Used by contains_label_[p1]. */ + +struct contains_label_data +{ + hash_set<tree> *pset; + bool inside_switch_p; +}; + /* Callback for walk_tree, looking for LABEL_EXPR. Return *TP if it is - a LABEL_EXPR; otherwise return NULL_TREE. Do not check the subtrees - of GOTO_EXPR. */ + a LABEL_EXPR or CASE_LABEL_EXPR not inside of another SWITCH_EXPR; otherwise + return NULL_TREE. Do not check the subtrees of GOTO_EXPR. */ static tree -contains_label_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) +contains_label_1 (tree *tp, int *walk_subtrees, void *data) { + contains_label_data *d = (contains_label_data *) data; switch (TREE_CODE (*tp)) { case LABEL_EXPR: return *tp; + case CASE_LABEL_EXPR: + if (!d->inside_switch_p) + return *tp; + return NULL_TREE; + + case SWITCH_EXPR: + if (!d->inside_switch_p) + { + if (walk_tree (&SWITCH_COND (*tp), contains_label_1, data, d->pset)) + return *tp; + d->inside_switch_p = true; + if (walk_tree (&SWITCH_BODY (*tp), contains_label_1, data, d->pset)) + return *tp; + d->inside_switch_p = false; + *walk_subtrees = 0; + } + return NULL_TREE; + case GOTO_EXPR: *walk_subtrees = 0; - - /* ... fall through ... */ + return NULL_TREE; default: return NULL_TREE; @@ -11564,8 +11590,9 @@ contains_label_1 (tree *tp, int *walk_su static bool contains_label_p (tree st) { - return - (walk_tree_without_duplicates (&st, contains_label_1 , NULL) != NULL_TREE); + hash_set<tree> pset; + contains_label_data data = { &pset, false }; + return walk_tree (&st, contains_label_1, &data, &pset) != NULL_TREE; } /* Fold a ternary expression of code CODE and type TYPE with operands --- gcc/testsuite/c-c++-common/torture/pr83553.c (nonexistent) +++ gcc/testsuite/c-c++-common/torture/pr83553.c (revision 255988) @@ -0,0 +1,29 @@ +/* PR c++/83553 */ +/* { dg-do run } */ + +int a[3]; + +int +foo (int n) +{ + switch (n) + { + case 0: + for (n = 7, a[0]++; 0; a[2] = a[1] + 1) + { + case 2: + a[1] = a[0] + 1; + } + } + return n; +} + +int +main () +{ + if (foo (0) != 7 || a[0] != 1 || a[1] || a[2]) + __builtin_abort (); + if (foo (2) != 2 || a[0] != 1 || a[1] != 2 || a[2] != 3) + __builtin_abort (); + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-05 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/83605 * gimple-ssa-strength-reduction.c: Include tree-eh.h. (find_candidates_dom_walker::before_dom_children): Ignore stmts that can throw. * gcc.dg/pr83605.c: New test. --- gcc/gimple-ssa-strength-reduction.c (revision 256273) +++ gcc/gimple-ssa-strength-reduction.c (revision 256274) @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. #include "params.h" #include "tree-ssa-address.h" #include "tree-affine.h" +#include "tree-eh.h" #include "builtins.h" /* Information about a strength reduction candidate. Each statement @@ -1747,6 +1748,9 @@ find_candidates_dom_walker::before_dom_c { gimple *gs = gsi_stmt (gsi); + if (stmt_could_throw_p (gs)) + continue; + if (gimple_vuse (gs) && gimple_assign_single_p (gs)) slsr_process_ref (gs); --- gcc/testsuite/gcc.dg/pr83605.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83605.c (revision 256274) @@ -0,0 +1,20 @@ +/* PR tree-optimization/83605 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftrapv -fexceptions -fnon-call-exceptions" } */ + +int a; + +int +foo (int x) +{ + int b = a; + { + int c; + int *d = (x == 0) ? &c : &b; + + for (a = 0; a < 2; ++a) + c = (x + b) < a; + + return *d; + } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-09 Jakub Jelinek <ja...@redhat.com> PR preprocessor/83722 * gcc.c (try_generate_repro): Pass &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1] rather than &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1] as last argument to do_report_bug. --- gcc/gcc.c (revision 256366) +++ gcc/gcc.c (revision 256367) @@ -7035,8 +7035,8 @@ try_generate_repro (const char **argv) /* In final attempt we append compiler options and preprocesssed code to last generated .out file with configuration and backtrace. */ - char **output = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1]; - do_report_bug (new_argv, nargs, stderr_commented, output); + char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1]; + do_report_bug (new_argv, nargs, stderr_commented, err); } out:
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-18 Jakub Jelinek <ja...@redhat.com> PR c++/83824 * parser.c (attr_chainon): New function. (cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq, cp_parser_namespace_definition, cp_parser_init_declarator, cp_parser_type_specifier_seq, cp_parser_parameter_declaration, cp_parser_gnu_attributes_opt): Use it. (cp_parser_member_declaration, cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration): Likewise. Don't reset prefix_attributes if attributes is error_mark_node. * g++.dg/cpp0x/pr83824.C: New test. --- gcc/cp/parser.c (revision 256822) +++ gcc/cp/parser.c (revision 256823) @@ -10743,6 +10743,18 @@ cp_parser_statement (cp_parser* parser, "attributes at the beginning of statement are ignored"); } +/* Append ATTR to attribute list ATTRS. */ + +static tree +attr_chainon (tree attrs, tree attr) +{ + if (attrs == error_mark_node) + return error_mark_node; + if (attr == error_mark_node) + return error_mark_node; + return chainon (attrs, attr); +} + /* Parse the label for a labeled-statement, i.e. identifier : @@ -10862,7 +10874,7 @@ cp_parser_label_for_labeled_statement (c else if (!cp_parser_parse_definitely (parser)) ; else - attributes = chainon (attributes, attrs); + attributes = attr_chainon (attributes, attrs); } if (attributes != NULL_TREE) @@ -13194,8 +13206,7 @@ cp_parser_decl_specifier_seq (cp_parser* else { decl_specs->std_attributes - = chainon (decl_specs->std_attributes, - attrs); + = attr_chainon (decl_specs->std_attributes, attrs); if (decl_specs->locations[ds_std_attribute] == 0) decl_specs->locations[ds_std_attribute] = token->location; } @@ -13203,9 +13214,8 @@ cp_parser_decl_specifier_seq (cp_parser* } } - decl_specs->attributes - = chainon (decl_specs->attributes, - attrs); + decl_specs->attributes + = attr_chainon (decl_specs->attributes, attrs); if (decl_specs->locations[ds_attribute] == 0) decl_specs->locations[ds_attribute] = token->location; continue; @@ -18227,7 +18237,7 @@ cp_parser_namespace_definition (cp_parse if (post_ident_attribs) { if (attribs) - attribs = chainon (attribs, post_ident_attribs); + attribs = attr_chainon (attribs, post_ident_attribs); else attribs = post_ident_attribs; } @@ -19401,7 +19411,7 @@ cp_parser_init_declarator (cp_parser* pa decl = grokfield (declarator, decl_specifiers, initializer, !is_non_constant_init, /*asmspec=*/NULL_TREE, - chainon (attributes, prefix_attributes)); + attr_chainon (attributes, prefix_attributes)); if (decl && TREE_CODE (decl) == FUNCTION_DECL) cp_parser_save_default_args (parser, decl); cp_finalize_omp_declare_simd (parser, decl); @@ -20796,9 +20806,9 @@ cp_parser_type_specifier_seq (cp_parser* /* Check for attributes first. */ if (cp_next_tokens_can_be_attribute_p (parser)) { - type_specifier_seq->attributes = - chainon (type_specifier_seq->attributes, - cp_parser_attributes_opt (parser)); + type_specifier_seq->attributes + = attr_chainon (type_specifier_seq->attributes, + cp_parser_attributes_opt (parser)); continue; } @@ -21277,8 +21287,8 @@ cp_parser_parameter_declaration (cp_pars parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ decl_specifiers.attributes - = chainon (decl_specifiers.attributes, - cp_parser_attributes_opt (parser)); + = attr_chainon (decl_specifiers.attributes, + cp_parser_attributes_opt (parser)); /* If the declarator is a template parameter pack, remember that and clear the flag in the declarator itself so we don't get errors @@ -23268,7 +23278,7 @@ cp_parser_member_declaration (cp_parser* which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* Create the bitfield declaration. */ decl = grokbitfield (identifier @@ -23325,7 +23335,7 @@ cp_parser_member_declaration (cp_parser* which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* If it's an `=', then we have a constant-initializer or a pure-specifier. It is not correct to parse the @@ -23439,10 +23449,13 @@ cp_parser_member_declaration (cp_parser* cp_finalize_oacc_routine (parser, decl, false); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } /* If there is any qualification still in effect, clear it now; we will be starting fresh with the next declarator. */ @@ -24554,7 +24567,7 @@ cp_parser_gnu_attributes_opt (cp_parser* cp_parser_skip_to_end_of_statement (parser); /* Add these new attributes to the list. */ - attributes = chainon (attributes, attribute_list); + attributes = attr_chainon (attributes, attribute_list); } return attributes; @@ -29732,7 +29745,7 @@ cp_parser_objc_class_ivars (cp_parser* p which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); if (width) /* Create the bitfield declaration. */ @@ -29749,10 +29762,13 @@ cp_parser_objc_class_ivars (cp_parser* p objc_add_instance_variable (decl); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } token = cp_lexer_peek_token (parser->lexer); @@ -30282,8 +30298,8 @@ cp_parser_objc_struct_declaration (cp_pa which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); - + attributes = attr_chainon (prefix_attributes, attributes); + decl = grokfield (declarator, &declspecs, NULL_TREE, /*init_const_expr_p=*/false, NULL_TREE, attributes); @@ -30292,10 +30308,13 @@ cp_parser_objc_struct_declaration (cp_pa return error_mark_node; /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } DECL_CHAIN (decl) = decls; decls = decl; --- gcc/testsuite/g++.dg/cpp0x/pr83824.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/pr83824.C (revision 256823) @@ -0,0 +1,9 @@ +// PR c++/83824 +// { dg-do compile { target c++11 } } + +void +foo () +{ + if (alignas(1 alignas(1))) // { dg-error "expected" } + ; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-20 Jakub Jelinek <ja...@redhat.com> PR target/83930 * simplify-rtx.c (simplify_binary_operation_1) <case UMOD>: Use UINTVAL (trueop1) instead of INTVAL (op1). * gcc.dg/pr83930.c: New test. --- gcc/simplify-rtx.c (revision 256914) +++ gcc/simplify-rtx.c (revision 256915) @@ -3411,7 +3411,8 @@ simplify_binary_operation_1 (enum rtx_co if (CONST_INT_P (trueop1) && exact_log2 (UINTVAL (trueop1)) > 0) return simplify_gen_binary (AND, mode, op0, - gen_int_mode (INTVAL (op1) - 1, mode)); + gen_int_mode (UINTVAL (trueop1) - 1, + mode)); break; case MOD: --- gcc/testsuite/gcc.dg/pr83930.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83930.c (revision 256915) @@ -0,0 +1,17 @@ +/* PR target/83930 */ +/* { dg-do compile } */ +/* { dg-options "-Og -fno-tree-ccp -w" } */ + +unsigned __attribute__ ((__vector_size__ (16))) v; + +static inline void +bar (unsigned char d) +{ + v /= d; +} + +__attribute__ ((always_inline)) void +foo (void) +{ + bar (4); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-23 Jakub Jelinek <ja...@redhat.com> PR sanitizer/83987 * tree.c (cp_free_lang_data): Change DECL_VALUE_EXPR of DECL_OMP_PRIVATIZED_MEMBER vars to error_mark_node. * g++.dg/ubsan/pr83987.C: New test. --- gcc/cp/tree.c (revision 256996) +++ gcc/cp/tree.c (revision 256997) @@ -4844,6 +4844,16 @@ cp_free_lang_data (tree t) from the binding level. */ DECL_CHAIN (t) = NULL_TREE; } + /* Set DECL_VALUE_EXPRs of OpenMP privatized member artificial + decls to error_mark_node. These are DECL_IGNORED_P and after + OpenMP lowering they aren't useful anymore. Clearing DECL_VALUE_EXPR + doesn't work, as expansion could then consider them as something + to be expanded. */ + if (VAR_P (t) + && DECL_LANG_SPECIFIC (t) + && DECL_OMP_PRIVATIZED_MEMBER (t) + && DECL_IGNORED_P (t)) + SET_DECL_VALUE_EXPR (t, error_mark_node); } /* Stub for c-common. Please keep in sync with c-decl.c. --- gcc/testsuite/g++.dg/ubsan/pr83987.C (nonexistent) +++ gcc/testsuite/g++.dg/ubsan/pr83987.C (revision 256997) @@ -0,0 +1,15 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr -O0" } + +struct A { int i; }; +struct B : virtual A { void foo (); }; + +void +B::foo () +{ +#pragma omp sections lastprivate (i) + { + i = 0; + } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-27 Jakub Jelinek <ja...@redhat.com> PR middle-end/84040 * sched-deps.c (sched_macro_fuse_insns): Return immediately if !insn_set. --- gcc/sched-deps.c (revision 257118) +++ gcc/sched-deps.c (revision 257119) @@ -2851,9 +2851,11 @@ sched_macro_fuse_insns (rtx_insn *insn) { rtx insn_set = single_set (insn); + if (!insn_set) + return; + prev = prev_nonnote_nondebug_insn (insn); if (!prev - || !insn_set || !single_set (prev)) return;
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-29 Christoph Spiel <csp...@freenet.de> Jakub Jelinek <ja...@redhat.com> PR libgomp/84096 * omp.h.in (omp_init_nest_lock_with_hint): Use omp_nest_lock_t instead of omp_lock_t. --- libgomp/omp.h.in (revision 257166) +++ libgomp/omp.h.in (revision 257167) @@ -101,7 +101,7 @@ extern void omp_unset_lock (omp_lock_t * extern int omp_test_lock (omp_lock_t *) __GOMP_NOTHROW; extern void omp_init_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; -extern void omp_init_nest_lock_with_hint (omp_lock_t *, omp_lock_hint_t) +extern void omp_init_nest_lock_with_hint (omp_nest_lock_t *, omp_lock_hint_t) __GOMP_NOTHROW; extern void omp_destroy_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; extern void omp_set_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-30 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/83986 * sched-deps.c (sched_analyze_insn): For frame related insns, add anti dependence against last_pending_memory_flush in addition to pending_jump_insns. * gcc.dg/pr83986.c: New test. --- gcc/sched-deps.c (revision 257202) +++ gcc/sched-deps.c (revision 257203) @@ -2922,6 +2922,8 @@ sched_analyze_insn (struct deps_desc *de = alloc_INSN_LIST (insn, deps->sched_before_next_jump); /* Make sure epilogue insn is scheduled after preceding jumps. */ + add_dependence_list (insn, deps->last_pending_memory_flush, 1, + REG_DEP_ANTI, true); add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI, true); } --- gcc/testsuite/gcc.dg/pr83986.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83986.c (revision 257203) @@ -0,0 +1,14 @@ +/* PR rtl-optimization/83986 */ +/* { dg-do compile } */ +/* { dg-options "-g -O2 -fsched2-use-superblocks -funwind-tables --param max-pending-list-length=1" } */ + +int v; + +int +foo (int x) +{ + v &= !!v && !!x; + if (v != 0) + foo (0); + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-10 Jakub Jelinek <ja...@redhat.com> PR sanitizer/83987 * omp-low.c (maybe_remove_omp_member_access_dummy_vars, remove_member_access_dummy_vars): New functions. (lower_omp_for, lower_omp_taskreg, lower_omp_target, lower_omp_1, execute_lower_omp): Use them. * tree.c (cp_free_lang_data): Revert 2018-01-23 change. * g++.dg/ubsan/pr83987-2.C: New test. --- gcc/omp-low.c (revision 257544) +++ gcc/omp-low.c (revision 257545) @@ -4079,6 +4079,43 @@ build_omp_barrier (tree lhs) return g; } +/* Remove omp_member_access_dummy_var variables from gimple_bind_vars + of BIND if in a method. */ + +static void +maybe_remove_omp_member_access_dummy_vars (gbind *bind) +{ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + { + tree vars = gimple_bind_vars (bind); + for (tree *pvar = &vars; *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + gimple_bind_set_vars (bind, vars); + } +} + +/* Remove omp_member_access_dummy_var variables from BLOCK_VARS of + block and its subblocks. */ + +static void +remove_member_access_dummy_vars (tree block) +{ + for (tree *pvar = &BLOCK_VARS (block); *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + + for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block)) + remove_member_access_dummy_vars (block); +} + /* If a context was created for STMT when it was scanned, return it. */ static omp_context * @@ -15254,6 +15291,7 @@ lower_omp_for (gimple_stmt_iterator *gsi pop_gimplify_context (new_stmt); gimple_bind_append_vars (new_stmt, ctx->block_vars); + maybe_remove_omp_member_access_dummy_vars (new_stmt); BLOCK_VARS (block) = gimple_bind_vars (new_stmt); if (BLOCK_VARS (block)) TREE_USED (block) = 1; @@ -15704,6 +15742,7 @@ lower_omp_taskreg (gimple_stmt_iterator /* Declare all the variables created by mapping and the variables declared in the scope of the parallel body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (par_bind); record_vars_into (gimple_bind_vars (par_bind), child_fn); if (ctx->record_type) @@ -16072,6 +16111,7 @@ lower_omp_target (gimple_stmt_iterator * /* Declare all the variables created by mapping and the variables declared in the scope of the target body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (tgt_bind); record_vars_into (gimple_bind_vars (tgt_bind), child_fn); } @@ -17060,6 +17100,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p break; case GIMPLE_BIND: lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx); + maybe_remove_omp_member_access_dummy_vars (as_a <gbind *> (stmt)); break; case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: @@ -17957,6 +17998,16 @@ execute_lower_omp (void) all_contexts = NULL; } BITMAP_FREE (task_shared_vars); + + /* If current function is a method, remove artificial dummy VAR_DECL created + for non-static data member privatization, they aren't needed for + debuginfo nor anything else, have been already replaced everywhere in the + IL and cause problems with LTO. */ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl)); return 0; } --- gcc/cp/tree.c (revision 257544) +++ gcc/cp/tree.c (revision 257545) @@ -4844,16 +4844,6 @@ cp_free_lang_data (tree t) from the binding level. */ DECL_CHAIN (t) = NULL_TREE; } - /* Set DECL_VALUE_EXPRs of OpenMP privatized member artificial - decls to error_mark_node. These are DECL_IGNORED_P and after - OpenMP lowering they aren't useful anymore. Clearing DECL_VALUE_EXPR - doesn't work, as expansion could then consider them as something - to be expanded. */ - if (VAR_P (t) - && DECL_LANG_SPECIFIC (t) - && DECL_OMP_PRIVATIZED_MEMBER (t) - && DECL_IGNORED_P (t)) - SET_DECL_VALUE_EXPR (t, error_mark_node); } /* Stub for c-common. Please keep in sync with c-decl.c. --- gcc/testsuite/g++.dg/ubsan/pr83987-2.C (nonexistent) +++ gcc/testsuite/g++.dg/ubsan/pr83987-2.C (revision 257545) @@ -0,0 +1,24 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr" } + +struct A +{ + int i; +}; + +struct B : virtual A +{ + void foo(); +}; + +void B::foo() +{ +#pragma omp parallel + { + #pragma omp sections lastprivate (i) + { + i = 0; + } + } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-12 Jakub Jelinek <ja...@redhat.com> PR c++/84341 * parser.c (cp_parser_binary_expression): Use build_min instead of build2_loc to build the no_toplevel_fold_p toplevel binary expression. * c-c++-common/gomp/pr84341.c: New test. --- gcc/cp/parser.c (revision 257606) +++ gcc/cp/parser.c (revision 257607) @@ -9330,12 +9330,14 @@ cp_parser_binary_expression (cp_parser* if (no_toplevel_fold_p && lookahead_prec <= current.prec && sp == stack) - current.lhs = build2_loc (combined_loc, - current.tree_type, - TREE_CODE_CLASS (current.tree_type) - == tcc_comparison - ? boolean_type_node : TREE_TYPE (current.lhs), - current.lhs, rhs); + { + current.lhs + = build_min (current.tree_type, + TREE_CODE_CLASS (current.tree_type) == tcc_comparison + ? boolean_type_node : TREE_TYPE (current.lhs), + current.lhs.get_value (), rhs.get_value ()); + SET_EXPR_LOCATION (current.lhs, combined_loc); + } else { current.lhs = build_x_binary_op (combined_loc, current.tree_type, --- gcc/testsuite/c-c++-common/gomp/pr84341.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr84341.c (revision 257607) @@ -0,0 +1,10 @@ +/* PR c++/84341 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +void +foo (int i) +{ + #pragma omp atomic + i = &i + 1; /* { dg-error "invalid form of" } */ +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-13 Jakub Jelinek <ja...@redhat.com> PR c/82210 * stor-layout.c (place_field): For variable length fields, adjust offset_align afterwards not just based on the field's alignment, but also on the size. * gcc.c-torture/execute/pr82210.c: New test. --- gcc/stor-layout.c (revision 257634) +++ gcc/stor-layout.c (revision 257635) @@ -1519,6 +1519,31 @@ place_field (record_layout_info rli, tre = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field)); rli->bitpos = bitsize_zero_node; rli->offset_align = MIN (rli->offset_align, desired_align); + + if (!multiple_of_p (bitsizetype, DECL_SIZE (field), + bitsize_int (rli->offset_align))) + { + tree type = strip_array_types (TREE_TYPE (field)); + /* The above adjusts offset_align just based on the start of the + field. The field might not have a size that is a multiple of + that offset_align though. If the field is an array of fixed + sized elements, assume there can be any multiple of those + sizes. If it is a variable length aggregate or array of + variable length aggregates, assume worst that the end is + just BITS_PER_UNIT aligned. */ + if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) + { + if (TREE_INT_CST_LOW (TYPE_SIZE (type))) + { + unsigned HOST_WIDE_INT sz + = TREE_INT_CST_LOW (TYPE_SIZE (type)); + sz = sz & -sz; + rli->offset_align = MIN (rli->offset_align, sz); + } + } + else + rli->offset_align = MIN (rli->offset_align, BITS_PER_UNIT); + } } else if (targetm.ms_bitfield_layout_p (rli->t)) { --- gcc/testsuite/gcc.c-torture/execute/pr82210.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr82210.c (revision 257635) @@ -0,0 +1,26 @@ +/* PR c/82210 */ + +void +foo (int size) +{ + int i; + struct S { + __attribute__((aligned (16))) struct T { short c; } a[size]; + int b[size]; + } s; + + for (i = 0; i < size; i++) + s.a[i].c = 0x1234; + for (i = 0; i < size; i++) + s.b[i] = 0; + for (i = 0; i < size; i++) + if (s.a[i].c != 0x1234 || s.b[i] != 0) + __builtin_abort (); +} + +int +main () +{ + foo (15); + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-16 Jakub Jelinek <ja...@redhat.com> PR ipa/84425 * ipa-inline.c (inline_small_functions): Fix a typo. * gcc.c-torture/compile/pr84425.c: New test. --- gcc/ipa-inline.c (revision 257771) +++ gcc/ipa-inline.c (revision 257772) @@ -1773,7 +1773,7 @@ inline_small_functions (void) struct cgraph_node *n2; int id = dfs->scc_no + 1; for (n2 = node; n2; - n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle) + n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle) { struct inline_summary *info2 = inline_summaries->get (n2); if (info2->scc_no) --- gcc/testsuite/gcc.c-torture/compile/pr84425.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr84425.c (revision 257772) @@ -0,0 +1,17 @@ +/* PR ipa/84425 */ + +void bar (int); + +void +foo (int x) +{ + if (x < 5) + bar (x); +} + +__attribute__((optimize(0))) void +bar (int x) +{ + if (x > 10) + foo (x); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-19 Jakub Jelinek <ja...@redhat.com> PR c++/84448 * parser.c (cp_parser_binary_expression): For no_toplevel_fold_p, if either operand is error_mark_node, set current.lhs to that instead of creating a binary op with error_mark_node operands. * g++.dg/gomp/pr84448.C: New test. --- gcc/cp/parser.c (revision 257820) +++ gcc/cp/parser.c (revision 257821) @@ -9331,12 +9331,18 @@ cp_parser_binary_expression (cp_parser* && lookahead_prec <= current.prec && sp == stack) { - current.lhs - = build_min (current.tree_type, - TREE_CODE_CLASS (current.tree_type) == tcc_comparison - ? boolean_type_node : TREE_TYPE (current.lhs), - current.lhs.get_value (), rhs.get_value ()); - SET_EXPR_LOCATION (current.lhs, combined_loc); + if (current.lhs == error_mark_node || rhs == error_mark_node) + current.lhs = error_mark_node; + else + { + current.lhs + = build_min (current.tree_type, + TREE_CODE_CLASS (current.tree_type) + == tcc_comparison + ? boolean_type_node : TREE_TYPE (current.lhs), + current.lhs.get_value (), rhs.get_value ()); + SET_EXPR_LOCATION (current.lhs, combined_loc); + } } else { --- gcc/testsuite/g++.dg/gomp/pr84448.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr84448.C (revision 257821) @@ -0,0 +1,17 @@ +// PR c++/84448 +// { dg-do compile } + +struct A +{ + operator int () const; + A& operator += (int); + A& operator ++ (); +}; + +void +foo (A a, A b) +{ + #pragma omp for + for (A i = a; i <=; ++i) // { dg-error "expected primary-expression before" } + ; // { dg-error "invalid controlling predicate" "" { target *-*-* } .-1 } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-26 Jakub Jelinek <ja...@redhat.com> PR c++/84558 * constexpr.c (cxx_eval_vec_init_1): For reuse, treat NULL eltinit like a valid constant initializer. Formatting fixes. * g++.dg/cpp1y/pr84558.C: New test. --- gcc/cp/constexpr.c (revision 258013) +++ gcc/cp/constexpr.c (revision 258014) @@ -2737,9 +2737,8 @@ cxx_eval_vec_init_1 (const constexpr_ctx if (!real_lvalue_p (init)) eltinit = move (eltinit); eltinit = force_rvalue (eltinit, tf_warning_or_error); - eltinit = (cxx_eval_constant_expression - (&new_ctx, eltinit, lval, - non_constant_p, overflow_p)); + eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval, + non_constant_p, overflow_p); } if (*non_constant_p && !ctx->quiet) break; @@ -2752,12 +2751,13 @@ cxx_eval_vec_init_1 (const constexpr_ctx else CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit); /* Reuse the result of cxx_eval_constant_expression call - from the first iteration to all others if it is a constant - initializer that doesn't require relocations. */ + from the first iteration to all others if it is a constant + initializer that doesn't require relocations. */ if (reuse && max > 1 - && (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) - == null_pointer_node)) + && (eltinit == NULL_TREE + || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) + == null_pointer_node))) { if (new_ctx.ctor != ctx->ctor) eltinit = new_ctx.ctor; --- gcc/testsuite/g++.dg/cpp1y/pr84558.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1y/pr84558.C (revision 258014) @@ -0,0 +1,6 @@ +// PR c++/84558 +// { dg-do compile { target c++14 } } + +struct A { static int i; constexpr A () { i = 0; } }; +struct B { A a[2][3][4]; }; +B b;
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-02 Jakub Jelinek <ja...@redhat.com> PR sanitizer/70875 * gcc.dg/ubsan/bounds-3.c: Add -fno-sanitize-recover=bounds to dg-options and dg-shouldfail "ubsan" directive. --- gcc/testsuite/gcc.dg/ubsan/bounds-3.c (revision 258116) +++ gcc/testsuite/gcc.dg/ubsan/bounds-3.c (revision 258117) @@ -1,6 +1,7 @@ /* PR sanitizer/70875 */ /* { dg-do run } */ -/* { dg-options "-fsanitize=bounds" } */ +/* { dg-options "-fsanitize=bounds -fno-sanitize-recover=bounds" } */ +/* { dg-shouldfail "ubsan" } */ int foo (int n, int k)
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-02 Jakub Jelinek <ja...@redhat.com> PR inline-asm/84625 * config/i386/i386.c (ix86_print_operand): Use conditional output_operand_lossage instead of gcc_assert if CONST_VECTOR is not zero vector. * gcc.target/i386/pr84625.c: New test. --- gcc/config/i386/i386.c (revision 258124) +++ gcc/config/i386/i386.c (revision 258125) @@ -18743,7 +18743,8 @@ ix86_print_operand (FILE *file, rtx x, i since we can in fact encode that into an immediate. */ if (GET_CODE (x) == CONST_VECTOR) { - gcc_assert (x == CONST0_RTX (GET_MODE (x))); + if (x != CONST0_RTX (GET_MODE (x))) + output_operand_lossage ("invalid vector immediate"); x = const0_rtx; } --- gcc/testsuite/gcc.target/i386/pr84625.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr84625.c (revision 258125) @@ -0,0 +1,12 @@ +/* PR inline-asm/84625 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2" } */ + +typedef int V __attribute__((vector_size (16))); + +void +foo (void) +{ + asm volatile ("# %0" : : "X" ((V) { 1, 2, 3, 4 })); // { dg-error "invalid vector immediate" } + asm volatile ("# %0" : : "" ((V) { 2, 3, 4, 5 })); // { dg-error "invalid vector immediate" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-02 Jakub Jelinek <ja...@redhat.com> PR c++/84662 * pt.c (tsubst_copy_and_build) <case TEMPLATE_ID_EXPR>: Use RETURN instead of return. <case POINTER_PLUS_EXPR>: Likewise. <case CONVERT_EXPR>: If op0 is error_mark_node, just return it instead of wrapping it into CONVERT_EXPR. * g++.dg/cpp1y/pr84662.C: New test. --- gcc/cp/pt.c (revision 258145) +++ gcc/cp/pt.c (revision 258146) @@ -16093,7 +16093,7 @@ tsubst_copy_and_build (tree t, if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); if (targs == error_mark_node) - return error_mark_node; + RETURN (error_mark_node); if (variable_template_p (templ)) RETURN (lookup_and_finish_template_variable (templ, targs, complain)); @@ -16158,6 +16158,8 @@ tsubst_copy_and_build (tree t, { tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); tree op0 = RECUR (TREE_OPERAND (t, 0)); + if (op0 == error_mark_node) + RETURN (error_mark_node); RETURN (build1 (CONVERT_EXPR, type, op0)); } @@ -16305,7 +16307,7 @@ tsubst_copy_and_build (tree t, { tree op0 = RECUR (TREE_OPERAND (t, 0)); tree op1 = RECUR (TREE_OPERAND (t, 1)); - return fold_build_pointer_plus (op0, op1); + RETURN (fold_build_pointer_plus (op0, op1)); } case SCOPE_REF: @@ -17111,7 +17113,7 @@ tsubst_copy_and_build (tree t, variadic capture proxy, we instantiate the elements when needed. */ gcc_assert (DECL_HAS_VALUE_EXPR_P (t)); - return RECUR (DECL_VALUE_EXPR (t)); + RETURN (RECUR (DECL_VALUE_EXPR (t))); } /* Fall through */ --- gcc/testsuite/g++.dg/cpp1y/pr84662.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1y/pr84662.C (revision 258146) @@ -0,0 +1,6 @@ +// PR c++/84662 +// { dg-do compile { target c++14 } } +// { dg-options "" } + +double b; +a (__attribute__((c (0 && int() - ([] {} && b) || auto)))); // { dg-error "expected constructor, destructor, or type conversion before" }
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-05 Jakub Jelinek <ja...@redhat.com> PR target/84700 * combine.c (combine_simplify_rtx): Don't try to simplify if if_then_else_cond returned non-NULL, but either true_rtx or false_rtx are equal to x. * gcc.target/powerpc/pr84700.c: New test. --- gcc/combine.c (revision 258262) +++ gcc/combine.c (revision 258263) @@ -5734,7 +5734,11 @@ combine_simplify_rtx (rtx x, machine_mod /* If everything is a comparison, what we have is highly unlikely to be simpler, so don't use it. */ && ! (COMPARISON_P (x) - && (COMPARISON_P (true_rtx) || COMPARISON_P (false_rtx)))) + && (COMPARISON_P (true_rtx) || COMPARISON_P (false_rtx))) + /* Similarly, if we end up with one of the expressions the same + as the original, it is certainly not simpler. */ + && ! rtx_equal_p (x, true_rtx) + && ! rtx_equal_p (x, false_rtx)) { rtx cop1 = const0_rtx; enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1); --- gcc/testsuite/gcc.target/powerpc/pr84700.c (nonexistent) +++ gcc/testsuite/gcc.target/powerpc/pr84700.c (revision 258263) @@ -0,0 +1,12 @@ +/* PR target/84700 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -misel" } */ + +long long int +foo (long long int x) +{ + long long int a = x < 2; + int b = a >= 0; + + return a + ((x == 0) ? a : b); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-08 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/84739 * tree-tailcall.c (find_tail_calls): Check call arguments against DECL_ARGUMENTS (current_function_decl) rather than DECL_ARGUMENTS (func) when checking for tail recursion. * gcc.dg/pr84739.c: New test. --- gcc/tree-tailcall.c (revision 258350) +++ gcc/tree-tailcall.c (revision 258351) @@ -481,7 +481,7 @@ find_tail_calls (basic_block bb, struct { tree arg; - for (param = DECL_ARGUMENTS (func), idx = 0; + for (param = DECL_ARGUMENTS (current_function_decl), idx = 0; param && idx < gimple_call_num_args (call); param = DECL_CHAIN (param), idx ++) { --- gcc/testsuite/gcc.dg/pr84739.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84739.c (revision 258351) @@ -0,0 +1,26 @@ +/* PR tree-optimization/84739 */ +/* { dg-do compile } */ +/* { dg-require-weak "" } */ +/* { dg-options "-O2 -w" } */ + +static void baz (void) __attribute__((weakref("bar"))); + +int +foo (int x, int y) +{ + if (x) + y = 0; + if (y) + goto lab; + y = 0; +lab: + return y; +} + +void +bar (int x, int y) +{ + y = foo (x, y); + if (y != 0) + baz (); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-09 Jakub Jelinek <ja...@redhat.com> PR c++/84767 * tree-inline.c (copy_tree_body_r): For INDIRECT_REF of a remapped decl, use remap_type if we want to use the type. * g++.dg/ext/vla18.C: New test. --- gcc/tree-inline.c (revision 258394) +++ gcc/tree-inline.c (revision 258395) @@ -1192,6 +1192,7 @@ copy_tree_body_r (tree *tp, int *walk_su *tp = gimple_fold_indirect_ref (ptr); if (! *tp) { + type = remap_type (type, id); if (TREE_CODE (ptr) == ADDR_EXPR) { *tp --- gcc/testsuite/g++.dg/ext/vla18.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/vla18.C (revision 258395) @@ -0,0 +1,19 @@ +// PR c++/84767 +// { dg-do compile } +// { dg-options "" } + +int v[1][10]; + +struct A +{ + A (int); +}; + +A::A (int i) +{ + typedef int T[1][i]; + T *x = (T *) v; + (*x)[0][0] = 0; +} + +A a = 10;
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-09 Jason Merrill <ja...@redhat.com> Jakub Jelinek <ja...@redhat.com> PR c++/84076 * call.c (convert_arg_to_ellipsis): Instead of cp_build_addr_expr build ADDR_EXPR with REFERENCE_TYPE. (build_over_call): For purposes of check_function_arguments, if argarray[j] is ADDR_EXPR with REFERENCE_TYPE created above, use its operand rather than the argument itself. * g++.dg/warn/Wformat-2.C: New test. --- gcc/cp/call.c (revision 258396) +++ gcc/cp/call.c (revision 258397) @@ -6837,7 +6837,7 @@ convert_arg_to_ellipsis (tree arg, tsubs "passing objects of non-trivially-copyable " "type %q#T through %<...%> is conditionally supported", arg_type); - return cp_build_addr_expr (arg, complain); + return build1 (ADDR_EXPR, build_reference_type (arg_type), arg); } } @@ -7578,7 +7578,15 @@ build_over_call (struct z_candidate *can tree *fargs = (!nargs ? argarray : (tree *) alloca (nargs * sizeof (tree))); for (j = 0; j < nargs; j++) - fargs[j] = maybe_constant_value (argarray[j]); + { + /* For -Wformat undo the implicit passing by hidden reference + done by convert_arg_to_ellipsis. */ + if (TREE_CODE (argarray[j]) == ADDR_EXPR + && TREE_CODE (TREE_TYPE (argarray[j])) == REFERENCE_TYPE) + fargs[j] = TREE_OPERAND (argarray[j], 0); + else + fargs[j] = maybe_constant_value (argarray[j]); + } check_function_arguments (input_location, TREE_TYPE (fn), nargs, fargs); } --- gcc/testsuite/g++.dg/warn/Wformat-2.C (nonexistent) +++ gcc/testsuite/g++.dg/warn/Wformat-2.C (revision 258397) @@ -0,0 +1,17 @@ +// PR c++/84076 +// { dg-do compile } +// { dg-options "-Wformat" } + +struct S { ~S (); }; +struct T { T (); T (const T &); }; + +void +foo () +{ + S s; + T t; + __builtin_printf ("%s\n", s); // { dg-warning "format '%s' expects argument of type 'char\\*', but argument 2 has type 'S'" } + __builtin_printf ("%s\n", t); // { dg-warning "format '%s' expects argument of type 'char\\*', but argument 2 has type 'T'" } + __builtin_printf ("%s\n", &s);// { dg-warning "format '%s' expects argument of type 'char\\*', but argument 2 has type 'S\\*'" } + __builtin_printf ("%s\n", &t);// { dg-warning "format '%s' expects argument of type 'char\\*', but argument 2 has type 'T\\*'" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-09 Jakub Jelinek <ja...@redhat.com> PR target/84772 * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Mark va_arg_tmp temporary TREE_ADDRESSABLE before gimplification of BUILT_IN_MEMCPY. * gcc.dg/pr84772.c: New test. --- gcc/config/rs6000/rs6000.c (revision 258398) +++ gcc/config/rs6000/rs6000.c (revision 258399) @@ -13537,6 +13537,7 @@ rs6000_gimplify_va_arg (tree valist, tre tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY), 3, dest_addr, addr, size_int (rsize * 4)); + TREE_ADDRESSABLE (tmp) = 1; gimplify_and_add (copy, pre_p); addr = dest_addr; --- gcc/testsuite/gcc.dg/pr84772.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84772.c (revision 258399) @@ -0,0 +1,13 @@ +/* PR target/84772 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized" } */ + +#include <stdarg.h> + +void +foo (int *x, int y, va_list ap) +{ + __builtin_memset (x, 0, sizeof (int)); + for (int i = 0; i < y; i++) + va_arg (ap, long double); /* { dg-bogus "uninitialized" } */ +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-15 Jakub Jelinek <ja...@redhat.com> PR c++/84222 * cp-tree.h (cp_warn_deprecated_use): Declare. * tree.c (cp_warn_deprecated_use): New function. * typeck2.c (build_functional_cast): Use it. * decl.c (grokparms): Likewise. (grokdeclarator): Likewise. Temporarily push nested class scope around grokparms call for out of class member definitions. * g++.dg/warn/deprecated.C (T::member3): Change dg-warning to dg-bogus. * g++.dg/warn/deprecated-6.C (T::member3): Likewise. * g++.dg/warn/deprecated-13.C: New test. --- gcc/cp/decl.c (revision 258567) +++ gcc/cp/decl.c (revision 258568) @@ -9594,7 +9594,7 @@ grokdeclarator (const cp_declarator *dec suppress reports of deprecated items. */ if (type && TREE_DEPRECATED (type) && deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (type, NULL_TREE); + cp_warn_deprecated_use (type); if (type && TREE_CODE (type) == TYPE_DECL) { typedef_decl = type; @@ -9602,7 +9602,7 @@ grokdeclarator (const cp_declarator *dec if (TREE_DEPRECATED (type) && DECL_ARTIFICIAL (typedef_decl) && deprecated_state != DEPRECATED_SUPPRESS) - warn_deprecated_use (type, NULL_TREE); + cp_warn_deprecated_use (type); } /* No type at all: default to `int', and set DEFAULTED_INT because it was not a user-defined typedef. */ @@ -10287,8 +10287,18 @@ grokdeclarator (const cp_declarator *dec error ("a conversion function cannot have a trailing return type"); } - arg_types = grokparms (declarator->u.function.parameters, - &parms); + tree pushed_scope = NULL_TREE; + if (funcdecl_p + && decl_context != FIELD + && inner_declarator->u.id.qualifying_scope + && CLASS_TYPE_P (inner_declarator->u.id.qualifying_scope)) + pushed_scope + = push_scope (inner_declarator->u.id.qualifying_scope); + + arg_types = grokparms (declarator->u.function.parameters, &parms); + + if (pushed_scope) + pop_scope (pushed_scope); if (inner_declarator && inner_declarator->kind == cdk_id @@ -11782,7 +11792,7 @@ grokparms (tree parmlist, tree *parms) { tree deptype = type_is_deprecated (type); if (deptype) - warn_deprecated_use (deptype, NULL_TREE); + cp_warn_deprecated_use (deptype); } /* Top-level qualifiers on the parameters are --- gcc/cp/tree.c (revision 258567) +++ gcc/cp/tree.c (revision 258568) @@ -5347,6 +5347,19 @@ cp_tree_code_length (enum tree_code code } } +/* Wrapper around warn_deprecated_use that doesn't warn for + current_class_type. */ + +void +cp_warn_deprecated_use (tree node) +{ + if (TYPE_P (node) + && current_class_type + && TYPE_MAIN_VARIANT (node) == current_class_type) + return; + warn_deprecated_use (node, NULL_TREE); +} + /* Implement -Wzero_as_null_pointer_constant. Return true if the conditions for the warning hold, false otherwise. */ bool --- gcc/cp/typeck2.c (revision 258567) +++ gcc/cp/typeck2.c (revision 258568) @@ -2057,7 +2057,7 @@ build_functional_cast (tree exp, tree pa if (complain & tf_warning && TREE_DEPRECATED (type) && DECL_ARTIFICIAL (exp)) - warn_deprecated_use (type, NULL_TREE); + cp_warn_deprecated_use (type); } else type = exp; --- gcc/cp/cp-tree.h (revision 258567) +++ gcc/cp/cp-tree.h (revision 258568) @@ -7064,6 +7064,7 @@ extern tree cxx_copy_lang_qualifiers (c extern void cxx_print_statistics (void); extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t); +extern void cp_warn_deprecated_use (tree); /* in ptree.c */ extern void cxx_print_xnode (FILE *, tree, int); --- gcc/testsuite/g++.dg/warn/deprecated-6.C (revision 258567) +++ gcc/testsuite/g++.dg/warn/deprecated-6.C (revision 258568) @@ -98,7 +98,7 @@ T *p3; // { dg-warning "'T' is deprec inline void T::member1(int) {} -int T::member3(T *p) // { dg-warning "'T' is deprecated: Please avoid T" } +int T::member3(T *p) // { dg-bogus "'T' is deprecated: Please avoid T" } { p->member1(1); /* { dg-warning "'void T::member1\\(int\\)' is deprecated: Please avoid member1" "" } */ (*p).member1(2); /* { dg-warning "'void T::member1\\(int\\)' is deprecated: Please avoid member1" "" } */ --- gcc/testsuite/g++.dg/warn/deprecated.C (revision 258567) +++ gcc/testsuite/g++.dg/warn/deprecated.C (revision 258568) @@ -102,7 +102,7 @@ T *p3; // { dg-warning "'T' is deprec inline void T::member1(int) {} -int T::member3(T *p) // { dg-warning "'T' is deprecated" } +int T::member3(T *p) // { dg-bogus "'T' is deprecated" } { p->member1(1); /* { dg-warning "'void T::member1\\(int\\)' is deprecated" "" } */ (*p).member1(2); /* { dg-warning "'void T::member1\\(int\\)' is deprecated" "" } */ @@ -113,5 +113,3 @@ int T::member3(T *p) // { dg-warning "' return f1(); /* { dg-warning "'INT1 f1\\(\\)' is deprecated" "" } */ } #endif - - --- gcc/testsuite/g++.dg/warn/deprecated-13.C (nonexistent) +++ gcc/testsuite/g++.dg/warn/deprecated-13.C (revision 258568) @@ -0,0 +1,44 @@ +// PR c++/84222 +// { dg-do compile } + +struct __attribute__((deprecated)) C { // { dg-message "declared here" } + C () {} + C (const C &); // { dg-bogus "'C' is deprecated" } + C (const C &x, const C &y) { C z = x; } // { dg-bogus "'C' is deprecated" } + void foo (const C &x, const C &y); // { dg-bogus "'C' is deprecated" } +}; + +void +C::foo (const C &x, const C &y) // { dg-bogus "'C' is deprecated" } +{ + C z = x; // { dg-bogus "'C' is deprecated" } +} + +void +bar (const C &x, const C &y) // { dg-warning "'C' is deprecated" } +{ + C z = x; // { dg-warning "'C' is deprecated" } +} + +template <int N> +struct __attribute__((deprecated)) D { // { dg-message "declared here" } + D () {} + D (const D &); // { dg-bogus "is deprecated" } + D (const D &x, const D &y) { D z = x; } // { dg-bogus "is deprecated" } + void foo (const D &x, const D &y); // { dg-bogus "is deprecated" } +}; + +template <int N> +void +D<N>::foo // { dg-bogus "is deprecated" "" { xfail *-*-* } } +(const D &x, const D &y) // { dg-bogus "is deprecated" } +{ + D z = x; // { dg-bogus "is deprecated" } +} + +template <int N> +void +bar (const D<N> &x, const D<N> &y) // { dg-warning "is deprecated" } +{ + D<N> z = x; // { dg-warning "is deprecated" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-15 Jakub Jelinek <ja...@redhat.com> PR c++/79085 * calls.c (expand_call): For TREE_ADDRESSABLE rettype ignore alignment check and use address of target always. * g++.dg/opt/pr79085.C: New test. --- gcc/calls.c (revision 258573) +++ gcc/calls.c (revision 258574) @@ -3147,9 +3147,14 @@ expand_call (tree exp, rtx target, int i if (CALL_EXPR_RETURN_SLOT_OPT (exp) && target && MEM_P (target) - && !(MEM_ALIGN (target) < TYPE_ALIGN (rettype) - && SLOW_UNALIGNED_ACCESS (TYPE_MODE (rettype), - MEM_ALIGN (target)))) + /* If rettype is addressable, we may not create a temporary. + If target is properly aligned at runtime and the compiler + just doesn't know about it, it will work fine, otherwise it + will be UB. */ + && (TREE_ADDRESSABLE (rettype) + || !(MEM_ALIGN (target) < TYPE_ALIGN (rettype) + && SLOW_UNALIGNED_ACCESS (TYPE_MODE (rettype), + MEM_ALIGN (target))))) structure_value_addr = XEXP (target, 0); else { --- gcc/testsuite/g++.dg/opt/pr79085.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr79085.C (revision 258574) @@ -0,0 +1,24 @@ +// PR c++/79085 +// { dg-do compile } +// { dg-options "-Os" } +// { dg-additional-options "-mstrict-align" { target { aarch64*-*-* powerpc*-*-linux* powerpc*-*-elf* } } } + +void *operator new (__SIZE_TYPE__, void *p) { return p; } + +struct S +{ + S (); + S (const S &); + ~S (void); + int i; +}; + +S foo (); + +static char buf [sizeof (S) + 1]; + +S * +bar () +{ + return new (buf + 1) S (foo ()); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-16 Jakub Jelinek <ja...@redhat.com> PR c++/84874 * decl.c (reshape_init_class): Don't assert d->cur->index == field if d->cur->index is a FIELD_DECL, instead set field to d->cur->index. * g++.dg/cpp1z/desig7.C: New test. --- gcc/cp/decl.c (revision 258584) +++ gcc/cp/decl.c (revision 258585) @@ -5796,8 +5796,18 @@ reshape_init_class (tree type, reshape_i return error_mark_node; if (TREE_CODE (d->cur->index) == FIELD_DECL) - /* We already reshaped this. */ - gcc_assert (d->cur->index == field); + { + /* We already reshaped this. */ + if (field != d->cur->index) + { + tree id = DECL_NAME (d->cur->index); + gcc_assert (id); + gcc_checking_assert (lookup_field_1 (type, id, + /*want_type=*/false) + == d->cur->index); + field = d->cur->index; + } + } else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE) field = lookup_field_1 (type, d->cur->index, /*want_type=*/false); else --- gcc/testsuite/g++.dg/cpp1z/desig7.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/desig7.C (revision 258585) @@ -0,0 +1,18 @@ +// PR c++/84874 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { int a, b; }; +struct B { A d; }; + +void +foo (B *x) +{ + *x = { .d = { .b = 5 } }; // { dg-message "non-trivial designated initializers not supported" } +} + +void +bar (A *x) +{ + *x = { .b = 6 }; // { dg-message "non-trivial designated initializers not supported" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-16 Jakub Jelinek <ja...@redhat.com> PR c++/84874 * g++.dg/cpp1z/desig8.C: New test. --- gcc/testsuite/g++.dg/cpp1z/desig8.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/desig8.C (revision 258588) @@ -0,0 +1,18 @@ +// PR c++/84874 +// { dg-do compile { target c++1z } } +// { dg-options "" } + +struct A { int a; struct { int b; }; }; +struct B { A d; }; + +void +foo (B *x) +{ + *x = { .d = { .b = 5 } }; // { dg-message "non-trivial designated initializers not supported" } +} + +void +bar (A *x) +{ + *x = { .b = 6 }; // { dg-message "non-trivial designated initializers not supported" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-16 Jakub Jelinek <ja...@redhat.com> PR target/84899 * postreload.c (reload_combine_recognize_pattern): Perform INTVAL addition in unsigned HOST_WIDE_INT type to avoid UB and truncate_int_for_mode the result for the destination's mode. * gcc.dg/pr84899.c: New test. --- gcc/postreload.c (revision 258609) +++ gcc/postreload.c (revision 258610) @@ -1157,11 +1157,13 @@ reload_combine_recognize_pattern (rtx_in value in PREV, the constant loading instruction. */ validate_change (prev, &SET_DEST (prev_set), index_reg, 1); if (reg_state[regno].offset != const0_rtx) - validate_change (prev, - &SET_SRC (prev_set), - GEN_INT (INTVAL (SET_SRC (prev_set)) - + INTVAL (reg_state[regno].offset)), - 1); + { + HOST_WIDE_INT c + = trunc_int_for_mode (UINTVAL (SET_SRC (prev_set)) + + UINTVAL (reg_state[regno].offset), + GET_MODE (index_reg)); + validate_change (prev, &SET_SRC (prev_set), GEN_INT (c), 1); + } /* Now for every use of REG that we have recorded, replace REG with REG_SUM. */ --- gcc/testsuite/gcc.dg/pr84899.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84899.c (revision 258610) @@ -0,0 +1,12 @@ +/* PR target/84899 */ +/* { dg-do compile } */ +/* { dg-options "-O -funroll-all-loops -fno-move-loop-invariants" } */ + +void +foo (int x) +{ + int a = 1 / x, b = 0; + + while ((a + b + 1) < x) + b = __INT_MAX__; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-20 Jakub Jelinek <ja...@redhat.com> PR c/84953 * builtins.c (fold_builtin_strpbrk): For strpbrk(x, "") use type instead of TREE_TYPE (s1) for the return value. * gcc.dg/pr84953.c: New test. --- gcc/builtins.c (revision 258670) +++ gcc/builtins.c (revision 258671) @@ -9573,7 +9573,7 @@ fold_builtin_strpbrk (location_t loc, tr if (p2[0] == '\0') /* strpbrk(x, "") == NULL. Evaluate and ignore s1 in case it had side-effects. */ - return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1); + return omit_one_operand_loc (loc, type, integer_zero_node, s1); if (p2[1] != '\0') return NULL_TREE; /* Really call strpbrk. */ --- gcc/testsuite/gcc.dg/pr84953.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84953.c (revision 258671) @@ -0,0 +1,11 @@ +/* PR c/84953 */ +/* { dg-do compile } */ + +char *strpbrk (const char *, const char *); + +char * +test (char *p) +{ + p = strpbrk (p, ""); /* { dg-bogus "assignment discards 'const' qualifier from pointer target type" } */ + return p; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-20 Jakub Jelinek <ja...@redhat.com> PR debug/84875 * dce.c (delete_unmarked_insns): Don't remove frame related noop moves holding REG_CFA_RESTORE notes, instead turn them into a USE. * gcc.dg/pr84875.c: New test. --- gcc/dce.c (revision 258691) +++ gcc/dce.c (revision 258692) @@ -569,9 +569,19 @@ delete_unmarked_insns (void) FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next) if (NONDEBUG_INSN_P (insn)) { + rtx turn_into_use = NULL_RTX; + /* Always delete no-op moves. */ if (noop_move_p (insn)) - ; + { + if (RTX_FRAME_RELATED_P (insn)) + turn_into_use + = find_reg_note (insn, REG_CFA_RESTORE, NULL); + if (turn_into_use && REG_P (XEXP (turn_into_use, 0))) + turn_into_use = XEXP (turn_into_use, 0); + else + turn_into_use = NULL_RTX; + } /* Otherwise rely only on the DCE algorithm. */ else if (marked_insn_p (insn)) @@ -611,8 +621,19 @@ delete_unmarked_insns (void) if (CALL_P (insn)) must_clean = true; - /* Now delete the insn. */ - delete_insn_and_edges (insn); + if (turn_into_use) + { + /* Don't remove frame related noop moves if they cary + REG_CFA_RESTORE note, while we don't need to emit any code, + we need it to emit the CFI restore note. */ + PATTERN (insn) + = gen_rtx_USE (GET_MODE (turn_into_use), turn_into_use); + INSN_CODE (insn) = -1; + df_insn_rescan (insn); + } + else + /* Now delete the insn. */ + delete_insn_and_edges (insn); } /* Deleted a pure or const call. */ --- gcc/testsuite/gcc.dg/pr84875.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84875.c (revision 258692) @@ -0,0 +1,28 @@ +/* PR debug/84875 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-additional-options "-fpie" { target pie } } */ +/* { dg-additional-options "-march=z196" { target s390*-*-* } } */ + +static long *a[100]; +static int b[100]; +long *c; +int d; +void foo (long *); + +void +bar () +{ + long *g = c; + g--; + d = *g; + if (d) + if (b[d] < 8) + { + *(void **)g = a[d]; + a[d] = g; + b[d]++; + return; + } + foo (g); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-22 Jakub Jelinek <ja...@redhat.com> PR inline-asm/84941 * function.c (match_asm_constraints_1): Don't do the optimization if input isn't a REG, SUBREG, MEM or constant. * gcc.dg/pr84941.c: New test. --- gcc/function.c (revision 258763) +++ gcc/function.c (revision 258764) @@ -6662,7 +6662,9 @@ match_asm_constraints_1 (rtx_insn *insn, if (! REG_P (output) || rtx_equal_p (output, input) || (GET_MODE (input) != VOIDmode - && GET_MODE (input) != GET_MODE (output))) + && GET_MODE (input) != GET_MODE (output)) + || !(REG_P (input) || SUBREG_P (input) + || MEM_P (input) || CONSTANT_P (input))) continue; /* We can't do anything if the output is also used as input, --- gcc/testsuite/gcc.dg/pr84941.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84941.c (revision 258764) @@ -0,0 +1,10 @@ +/* PR inline-asm/84941 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +foo (void) +{ + short *b[1] = { 0 }; + asm volatile ("" : "=m,m" (b), "=r,r" (b) : "1,p" (b)); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-23 Jakub Jelinek <ja...@redhat.com> PR inline-asm/85022 * alias.c (write_dependence_p): Don't require for x_canonicalized non-VOIDmode if x has VOIDmode. * c-c++-common/torture/pr85022.c: New test. --- gcc/alias.c (revision 258794) +++ gcc/alias.c (revision 258795) @@ -2999,7 +2999,8 @@ write_dependence_p (const_rtx mem, int ret; gcc_checking_assert (x_canonicalized - ? (x_addr != NULL_RTX && x_mode != VOIDmode) + ? (x_addr != NULL_RTX + && (x_mode != VOIDmode || GET_MODE (x) == VOIDmode)) : (x_addr == NULL_RTX && x_mode == VOIDmode)); if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) --- gcc/testsuite/c-c++-common/torture/pr85022.c (nonexistent) +++ gcc/testsuite/c-c++-common/torture/pr85022.c (revision 258795) @@ -0,0 +1,9 @@ +/* PR inline-asm/85022 */ + +extern struct B b; + +void +foo () +{ + __asm ("" : "+m" (b)); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-23 Jakub Jelinek <ja...@redhat.com> PR inline-asm/85034 * function.c (match_asm_constraints_1): Don't optimize if input doesn't satisfy general_operand predicate for output's mode. * gcc.target/i386/pr85034.c: New test. --- gcc/function.c (revision 258795) +++ gcc/function.c (revision 258796) @@ -6661,10 +6661,9 @@ match_asm_constraints_1 (rtx_insn *insn, /* Only do the transformation for pseudos. */ if (! REG_P (output) || rtx_equal_p (output, input) - || (GET_MODE (input) != VOIDmode - && GET_MODE (input) != GET_MODE (output)) || !(REG_P (input) || SUBREG_P (input) - || MEM_P (input) || CONSTANT_P (input))) + || MEM_P (input) || CONSTANT_P (input)) + || !general_operand (input, GET_MODE (output))) continue; /* We can't do anything if the output is also used as input, --- gcc/testsuite/gcc.target/i386/pr85034.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr85034.c (revision 258796) @@ -0,0 +1,11 @@ +/* PR inline-asm/85034 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +foo (void) +{ + volatile float a; + struct S { char a; } b = { 0 }; + asm volatile ("" : "=r" (a) : "0ir" (b)); +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-23 Jakub Jelinek <ja...@redhat.com> PR inline-asm/85022 * emit-rtl.c (init_emit_regs): Indicate that VOIDmode MEMs don't have known size by default. --- gcc/emit-rtl.c (revision 258822) +++ gcc/emit-rtl.c (revision 258823) @@ -6152,7 +6152,7 @@ init_emit_regs (void) attrs = ggc_cleared_alloc<mem_attrs> (); attrs->align = BITS_PER_UNIT; attrs->addrspace = ADDR_SPACE_GENERIC; - if (mode != BLKmode) + if (mode != BLKmode && mode != VOIDmode) { attrs->size_known_p = true; attrs->size = GET_MODE_SIZE (mode);
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-27 Jakub Jelinek <ja...@redhat.com> PR c++/85068 * class.c (update_vtable_entry_for_fn): Don't ICE if base_binfo is NULL. Assert if thunk_binfo is NULL then errorcount is non-zero. * g++.dg/inherit/covariant22.C: New test. --- gcc/cp/class.c (revision 258872) +++ gcc/cp/class.c (revision 258873) @@ -2479,19 +2479,20 @@ update_vtable_entry_for_fn (tree t, tree order. Of course it is lame that we have to repeat the search here anyway -- we should really be caching pieces of the vtable and avoiding this repeated work. */ - tree thunk_binfo, base_binfo; + tree thunk_binfo = NULL_TREE; + tree base_binfo = TYPE_BINFO (base_return); /* Find the base binfo within the overriding function's return type. We will always find a thunk_binfo, except when the covariancy is invalid (which we will have already diagnosed). */ - for (base_binfo = TYPE_BINFO (base_return), - thunk_binfo = TYPE_BINFO (over_return); - thunk_binfo; - thunk_binfo = TREE_CHAIN (thunk_binfo)) - if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo), - BINFO_TYPE (base_binfo))) - break; + if (base_binfo) + for (thunk_binfo = TYPE_BINFO (over_return); thunk_binfo; + thunk_binfo = TREE_CHAIN (thunk_binfo)) + if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo), + BINFO_TYPE (base_binfo))) + break; + gcc_assert (thunk_binfo || errorcount); /* See if virtual inheritance is involved. */ for (virtual_offset = thunk_binfo; --- gcc/testsuite/g++.dg/inherit/covariant22.C (nonexistent) +++ gcc/testsuite/g++.dg/inherit/covariant22.C (revision 258873) @@ -0,0 +1,19 @@ +// PR c++/85068 +// { dg-do compile } + +struct A; + +struct B +{ + virtual A *foo (); // { dg-error "overriding" } +}; + +struct C : virtual B +{ + virtual C *foo (); // { dg-error "invalid covariant return type for" } +}; + +struct D : C +{ + virtual C *foo (); +};
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-27 Jakub Jelinek <ja...@redhat.com> PR c++/85076 * tree.c (cp_build_reference_type): If to_type is error_mark_node, return it right away. * g++.dg/cpp1y/pr85076.C: New test. --- gcc/cp/tree.c (revision 258900) +++ gcc/cp/tree.c (revision 258901) @@ -962,6 +962,10 @@ tree cp_build_reference_type (tree to_type, bool rval) { tree lvalue_ref, t; + + if (to_type == error_mark_node) + return error_mark_node; + lvalue_ref = build_reference_type (to_type); if (!rval) return lvalue_ref; --- gcc/testsuite/g++.dg/cpp1y/pr85076.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1y/pr85076.C (revision 258901) @@ -0,0 +1,6 @@ +// PR c++/85076 +// { dg-do compile { target c++14 } } + +template<typename> struct A*; // { dg-error "expected unqualified-id before" } + +auto a = [](A<auto>) {}; // { dg-error "is not a template|has incomplete type" }
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-30 Jakub Jelinek <ja...@redhat.com> PR c++/84791 * semantics.c (finish_omp_reduction_clause): If OMP_CLAUSE_REDUCTION_PLACEHOLDER is error_mark_node, return true even if processing_template_decl. * g++.dg/gomp/pr84791.C: New test. --- gcc/cp/semantics.c (revision 258980) +++ gcc/cp/semantics.c (revision 258981) @@ -5623,7 +5623,11 @@ finish_omp_reduction_clause (tree c, boo return false; } else if (processing_template_decl) - return false; + { + if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node) + return true; + return false; + } tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c); --- gcc/testsuite/g++.dg/gomp/pr84791.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr84791.C (revision 258981) @@ -0,0 +1,15 @@ +// PR c++/84791 +// { dg-do compile } + +typedef int I; + +template <int> +void +foo () +{ + I i; + #pragma omp parallel reduction (I::I: i) // { dg-error "'I' is not a class, namespace, or enumeration" "" { target c++11 } } + ; // { dg-error "'I' is not a class or namespace" "" { target c++98_only } .-1 } +} + +template void foo<0> ();
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-03 Jakub Jelinek <ja...@redhat.com> PR c++/85140 * name-lookup.c (handle_namespace_attrs): Return early if attributes is error_mark_node. * g++.dg/cpp0x/gen-attrs-64.C: New test. --- gcc/cp/name-lookup.c (revision 259038) +++ gcc/cp/name-lookup.c (revision 259039) @@ -5044,6 +5044,9 @@ handle_namespace_attrs (tree ns, tree at tree d; bool saw_vis = false; + if (attributes == error_mark_node) + return false; + for (d = attributes; d; d = TREE_CHAIN (d)) { tree name = get_attribute_name (d); --- gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C (revision 259039) @@ -0,0 +1,4 @@ +// PR c++/85140 +// { dg-do compile { target c++11 } } + +namespace N alignas() {} // { dg-error "expected" }
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-03 Jakub Jelinek <ja...@redhat.com> PR c++/85147 * pt.c (fixed_parameter_pack_p_1): Punt if parm is error_mark_node. * g++.dg/cpp0x/pr85147.C: New test. --- gcc/cp/pt.c (revision 259039) +++ gcc/cp/pt.c (revision 259040) @@ -5101,7 +5101,7 @@ static void fixed_parameter_pack_p_1 (tree parm, struct find_parameter_pack_data *ppd) { /* A type parm can't refer to another parm. */ - if (TREE_CODE (parm) == TYPE_DECL) + if (TREE_CODE (parm) == TYPE_DECL || parm == error_mark_node) return; else if (TREE_CODE (parm) == PARM_DECL) { --- gcc/testsuite/g++.dg/cpp0x/pr85147.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/pr85147.C (revision 259040) @@ -0,0 +1,9 @@ +// PR c++/85147 +// { dg-do compile { target c++11 } } + +template<typename T> struct A +{ + template<template<...T> class...> struct B {}; // { dg-error "expected|mismatch" } +}; + +A<int>::B<> b; // { dg-error "does not name a template type" }
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-03 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/85167 * shrink-wrap.c (move_insn_for_shrink_wrap): Don't set bb_uses and bb_defs if *split_p, instead preinitialize it to NULL. * gcc.dg/pr85167.c: New test. --- gcc/shrink-wrap.c (revision 259057) +++ gcc/shrink-wrap.c (revision 259058) @@ -157,7 +157,7 @@ move_insn_for_shrink_wrap (basic_block b struct dead_debug_local *debug) { rtx set, src, dest; - bitmap live_out, live_in, bb_uses, bb_defs; + bitmap live_out, live_in, bb_uses = NULL, bb_defs = NULL; unsigned int i, dregno, end_dregno; unsigned int sregno = FIRST_PSEUDO_REGISTER; unsigned int end_sregno = FIRST_PSEUDO_REGISTER; @@ -330,8 +330,11 @@ move_insn_for_shrink_wrap (basic_block b /* Check whether BB uses DEST or clobbers DEST. We need to add INSN to BB if so. Either way, DEST is no longer live on entry, except for any part that overlaps SRC (next loop). */ - bb_uses = &DF_LR_BB_INFO (bb)->use; - bb_defs = &DF_LR_BB_INFO (bb)->def; + if (!*split_p) + { + bb_uses = &DF_LR_BB_INFO (bb)->use; + bb_defs = &DF_LR_BB_INFO (bb)->def; + } if (df_live) { for (i = dregno; i < end_dregno; i++) --- gcc/testsuite/gcc.dg/pr85167.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr85167.c (revision 259058) @@ -0,0 +1,16 @@ +/* PR rtl-optimization/85167 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -w" } */ + +struct A { long b; }; +int c, d, e; +int bar (void); + +int +foo (void) +{ + long g; + for (; g == c ? 0 : (e = 1); g = ((struct A *)g)->b) + if (bar ()) + return d; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-06 Jakub Jelinek <ja...@redhat.com> PR debug/85252 * dwarf2out.c (rtl_for_decl_init): For STRING_CST initializer only build CONST_STRING if TYPE_MAX_VALUE is non-NULL and is INTEGER_CST. * gcc.dg/debug/pr85252.c: New test. --- gcc/dwarf2out.c (revision 259182) +++ gcc/dwarf2out.c (revision 259183) @@ -18749,6 +18749,8 @@ rtl_for_decl_init (tree init, tree type) if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) == 1 && domain + && TYPE_MAX_VALUE (domain) + && TREE_CODE (TYPE_MAX_VALUE (domain)) == INTEGER_CST && integer_zerop (TYPE_MIN_VALUE (domain)) && compare_tree_int (TYPE_MAX_VALUE (domain), TREE_STRING_LENGTH (init) - 1) == 0 --- gcc/testsuite/gcc.dg/debug/pr85252.c (nonexistent) +++ gcc/testsuite/gcc.dg/debug/pr85252.c (revision 259183) @@ -0,0 +1,11 @@ +/* PR debug/85252 */ +/* { dg-do compile } */ + +void +foo (void) +{ + static char a[0] = ""; + static char b[0] = "b"; /* { dg-warning "initializer-string for array of chars is too long" } */ + static char c[1] = "c"; + static char d[1] = "de"; /* { dg-warning "initializer-string for array of chars is too long" } */ +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-07 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/85257 * fold-const.c (native_encode_vector): If not all elts could fit and off is -1, return 0 rather than offset. * tree-ssa-sccvn.c (vn_reference_lookup_3): Pass (offset - offset2) / BITS_PER_UNIT as 4th argument to native_encode_expr. Verify len * BITS_PER_UNIT >= maxsizei. Don't adjust buffer in native_interpret_expr call. * gcc.dg/pr85257.c: New test. --- gcc/fold-const.c (revision 259205) +++ gcc/fold-const.c (revision 259206) @@ -7307,7 +7307,7 @@ native_encode_vector (const_tree expr, u return 0; offset += res; if (offset >= len) - return offset; + return (off == -1 && i < count - 1) ? 0 : offset; if (off != -1) off = 0; } --- gcc/tree-ssa-sccvn.c (revision 259205) +++ gcc/tree-ssa-sccvn.c (revision 259206) @@ -1814,8 +1814,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree int len; len = native_encode_expr (gimple_assign_rhs1 (def_stmt), - buffer, sizeof (buffer)); - if (len > 0) + buffer, sizeof (buffer), + (offset - offset2) / BITS_PER_UNIT); + if (len > 0 && len * BITS_PER_UNIT >= ref->size) { tree type = vr->type; /* Make sure to interpret in a type that has a range @@ -1824,10 +1825,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree && ref->size != TYPE_PRECISION (vr->type)) type = build_nonstandard_integer_type (ref->size, TYPE_UNSIGNED (type)); - tree val = native_interpret_expr (type, - buffer - + ((offset - offset2) - / BITS_PER_UNIT), + tree val = native_interpret_expr (type, buffer, ref->size / BITS_PER_UNIT); /* If we chop off bits because the types precision doesn't match the memory access size this is ok when optimizing --- gcc/testsuite/gcc.dg/pr85257.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr85257.c (revision 259206) @@ -0,0 +1,20 @@ +/* PR tree-optimization/85257 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2 -fno-tree-ccp" } */ + +typedef __int128 V __attribute__ ((__vector_size__ (16 * sizeof (__int128)))); + +__int128 __attribute__ ((noinline, noclone)) +foo (void) +{ + V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + return v[5]; +} + +int +main () +{ + if (foo () != 6) + __builtin_abort (); + return 0; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-10 Jakub Jelinek <ja...@redhat.com> PR fortran/85313 * openmp.c (resolve_omp_do): Remove bogus if (j < i) break;. (resolve_oacc_nested_loops): Likewise. Formatting fix. * gfortran.dg/gomp/pr85313.f90: New test. --- gcc/fortran/openmp.c (revision 259274) +++ gcc/fortran/openmp.c (revision 259275) @@ -5600,8 +5600,6 @@ resolve_omp_do (gfc_code *code) "iteration space at %L", name, &do_code->loc); break; } - if (j < i) - break; do_code2 = do_code2->block->next; } } @@ -5765,12 +5763,10 @@ resolve_oacc_nested_loops (gfc_code *cod || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->end) || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->step)) { - gfc_error ("!$ACC LOOP %s loops don't form rectangular iteration space at %L", - clause, &do_code->loc); + gfc_error ("!$ACC LOOP %s loops don't form rectangular " + "iteration space at %L", clause, &do_code->loc); break; } - if (j < i) - break; do_code2 = do_code2->block->next; } } --- gcc/testsuite/gfortran.dg/gomp/pr85313.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/gomp/pr85313.f90 (revision 259275) @@ -0,0 +1,25 @@ +! PR fortran/85313 +! { dg-do compile } + +!$omp do collapse(3) + do i = 1, 10 + do j = i, 20 ! { dg-error "form rectangular iteration space" } + do k = 1, 2 + end do + end do + end do +!$omp do collapse(3) + do i = 1, 10 + do j = 1, 5 + do k = i, 20 ! { dg-error "form rectangular iteration space" } + end do + end do + end do +!$omp do collapse(3) + do i = 1, 10 + do j = 1, 5 + do k = j, 20 ! { dg-error "form rectangular iteration space" } + end do + end do + end do +end
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-10 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/85300 * combine.c (subst): Handle subst of CONST_SCALAR_INT_P new_rtx also into FLOAT and UNSIGNED_FLOAT like ZERO_EXTEND, return a CLOBBER if simplify_unary_operation fails. * gcc.dg/pr85300.c: New test. --- gcc/combine.c (revision 259284) +++ gcc/combine.c (revision 259285) @@ -5575,11 +5575,15 @@ subst (rtx x, rtx from, rtx to, int in_d x = gen_rtx_CLOBBER (mode, const0_rtx); } else if (CONST_SCALAR_INT_P (new_rtx) - && GET_CODE (x) == ZERO_EXTEND) + && (GET_CODE (x) == ZERO_EXTEND + || GET_CODE (x) == FLOAT + || GET_CODE (x) == UNSIGNED_FLOAT)) { - x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), - new_rtx, GET_MODE (XEXP (x, 0))); - gcc_assert (x); + x = simplify_unary_operation (GET_CODE (x), GET_MODE (x), + new_rtx, + GET_MODE (XEXP (x, 0))); + if (!x) + return gen_rtx_CLOBBER (VOIDmode, const0_rtx); } else SUBST (XEXP (x, i), new_rtx); --- gcc/testsuite/gcc.dg/pr85300.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr85300.c (revision 259285) @@ -0,0 +1,16 @@ +/* PR rtl-optimization/85300 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -g -funroll-all-loops -fno-tree-ter -fno-web" } */ + +void +foo (double x, unsigned char y) +{ + while ((int) x < 1) + { + float a; + + a = y | 0x100; + y = 0; + x = a; + } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-17 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/85431 * dse.c (record_store): Ignore zero width stores. --- gcc/dse.c (revision 259447) +++ gcc/dse.c (revision 259448) @@ -1342,6 +1342,9 @@ record_store (rtx body, bb_info_t bb_inf else width = GET_MODE_SIZE (GET_MODE (mem)); + if (width == 0) + return 0; + if (group_id >= 0) { /* In the restrictive case where the base is a constant or the
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-05-06 Jakub Jelinek <ja...@redhat.com> PR c++/85659 * cfgexpand.c (expand_asm_stmt): Don't create a temporary if the type is addressable. Don't force op into register if it has BLKmode. * g++.dg/ext/asm14.C: New test. * g++.dg/ext/asm15.C: New test. * g++.dg/ext/asm16.C: New test. --- gcc/cfgexpand.c (revision 259981) +++ gcc/cfgexpand.c (revision 259982) @@ -3044,14 +3044,14 @@ expand_asm_stmt (gasm *stmt) generating_concat_p = 0; - if ((TREE_CODE (val) == INDIRECT_REF - && allows_mem) + if ((TREE_CODE (val) == INDIRECT_REF && allows_mem) || (DECL_P (val) && (allows_mem || REG_P (DECL_RTL (val))) && ! (REG_P (DECL_RTL (val)) && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type))) || ! allows_reg - || is_inout) + || is_inout + || TREE_ADDRESSABLE (type)) { op = expand_expr (val, NULL_RTX, VOIDmode, !allows_reg ? EXPAND_MEMORY : EXPAND_WRITE); @@ -3060,7 +3060,7 @@ expand_asm_stmt (gasm *stmt) if (! allows_reg && !MEM_P (op)) error ("output number %d not directly addressable", i); - if ((! allows_mem && MEM_P (op)) + if ((! allows_mem && MEM_P (op) && GET_MODE (op) != BLKmode) || GET_CODE (op) == CONCAT) { rtx old_op = op; --- gcc/testsuite/g++.dg/ext/asm14.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/asm14.C (revision 259982) @@ -0,0 +1,10 @@ +// PR c++/85659 +// { dg-do compile } + +struct S { S (); ~S (); int s; }; + +void +foo (S &s) +{ + __asm volatile ("" : "+m,r" (s) : : "memory"); +} --- gcc/testsuite/g++.dg/ext/asm15.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/asm15.C (revision 259982) @@ -0,0 +1,10 @@ +// PR c++/85659 +// { dg-do compile } + +struct S { S (); ~S (); int s; }; + +void +foo (S &s) +{ + __asm volatile ("" : "+r" (s) : : "memory"); // { dg-error "" } +} --- gcc/testsuite/g++.dg/ext/asm16.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/asm16.C (revision 259982) @@ -0,0 +1,10 @@ +// PR c++/85659 +// { dg-do compile } + +struct S { S (); ~S (); int s[64]; } s; + +void +foo () +{ + __asm volatile ("" : "=r" (s) : : "memory"); // { dg-error "" } +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-06-14 Jakub Jelinek <ja...@redhat.com> PR target/85945 * lower-subreg.c (find_decomposable_subregs): Don't decompose float subregs of multi-word pseudos unless the float mode has word size. * gcc.c-torture/compile/pr85945.c: New test. --- gcc/lower-subreg.c (revision 261593) +++ gcc/lower-subreg.c (revision 261594) @@ -497,7 +497,16 @@ find_decomposable_subregs (rtx *loc, enu were the same number and size of pieces. Hopefully this doesn't happen much. */ - if (outer_words == 1 && inner_words > 1) + if (outer_words == 1 + && inner_words > 1 + /* Don't allow to decompose floating point subregs of + multi-word pseudos if the floating point mode does + not have word size, because otherwise we'd generate + a subreg with that floating mode from a different + sized integral pseudo which is not allowed by + validate_subreg. */ + && (!FLOAT_MODE_P (GET_MODE (x)) + || outer_size == UNITS_PER_WORD)) { bitmap_set_bit (decomposable_context, regno); iter.skip_subrtxes (); --- gcc/testsuite/gcc.c-torture/compile/pr85945.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr85945.c (revision 261594) @@ -0,0 +1,16 @@ +/* PR target/85945 */ + +typedef float V __attribute__((vector_size(16))); +union U { V v; float f[4]; }; +int f; +float g[4]; + +void +foo (void) +{ + V d; + union U i; + i.v = d; + for (f = 0; f < 4; f++) + g[f] = i.f[f]; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-06-15 Jakub Jelinek <ja...@redhat.com> PR middle-end/85878 * expr.c (expand_assignment): Only call store_expr for halves if the mode is the same. * gfortran.fortran-torture/compile/pr85878.f90: New test. --- gcc/expr.c (revision 261659) +++ gcc/expr.c (revision 261660) @@ -5109,7 +5109,10 @@ expand_assignment (tree to, tree from, b && bitpos == 0 && bitsize == mode_bitsize) result = store_expr (from, to_rtx, false, nontemporal, reversep); - else if (bitsize == mode_bitsize / 2 + else if (COMPLEX_MODE_P (GET_MODE (to_rtx)) + && (TYPE_MODE (TREE_TYPE (from)) + == GET_MODE_INNER (GET_MODE (to_rtx))) + && bitsize == mode_bitsize / 2 && (bitpos == 0 || bitpos == mode_bitsize / 2)) result = store_expr (from, XEXP (to_rtx, bitpos != 0), false, nontemporal, reversep); --- gcc/testsuite/gfortran.fortran-torture/compile/pr85878.f90 (nonexistent) +++ gcc/testsuite/gfortran.fortran-torture/compile/pr85878.f90 (revision 261660) @@ -0,0 +1,8 @@ +! PR middle-end/85878 + +program pr85878 + real :: a + complex :: c = (2.0, 3.0) + print *, c + print *, transfer (a, c) +end
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-06-20 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/86231 * tree-vrp.c (union_ranges): For ( [ ) ] or ( )[ ] range and anti-range don't overwrite *vr0min before using it to compute *vr0max. * gcc.dg/tree-ssa/vrp119.c: New test. * gcc.c-torture/execute/pr86231.c: New test. --- gcc/tree-vrp.c (revision 261805) +++ gcc/tree-vrp.c (revision 261806) @@ -5922,9 +5922,9 @@ union_ranges (enum value_range_type *vr0 if (TREE_CODE (*vr0min) == INTEGER_CST) { *vr0type = vr1type; - *vr0min = vr1min; *vr0max = int_const_binop (MINUS_EXPR, *vr0min, build_int_cst (TREE_TYPE (*vr0min), 1)); + *vr0min = vr1min; } else goto give_up; --- gcc/testsuite/gcc.c-torture/execute/pr86231.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr86231.c (revision 261806) @@ -0,0 +1,30 @@ +/* PR tree-optimization/86231 */ + +#define ONE ((void *) 1) +#define TWO ((void *) 2) + +__attribute__((noinline, noclone)) int +foo (void *p, int x) +{ + if (p == ONE) return 0; + if (!p) + p = x ? TWO : ONE; + return p == ONE ? 0 : 1; +} + +int v[8]; + +int +main () +{ + if (foo ((void *) 0, 0) != 0 + || foo ((void *) 0, 1) != 1 + || foo (ONE, 0) != 0 + || foo (ONE, 1) != 0 + || foo (TWO, 0) != 1 + || foo (TWO, 1) != 1 + || foo (&v[7], 0) != 1 + || foo (&v[7], 1) != 1) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.dg/tree-ssa/vrp119.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/vrp119.c (revision 261806) @@ -0,0 +1,20 @@ +/* PR tree-optimization/86231 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ +/* { dg-final { scan-tree-dump-not "link_error" "vrp1" } } */ + +int bar (int); +void link_error (void); + +int +foo (int x, int y, int z) +{ + if (x < 4 || x > 8) __builtin_unreachable (); + if (y >= 2 && y <= 6) __builtin_unreachable (); + /* x is [4, 8], y is ~[2, 6], resulting range of e should be ~[2, 3]. */ + int e = (z ? x : y); + bar (bar (bar (bar (bar (bar (bar (bar (bar (bar (bar (bar (e)))))))))))); + if (e == 2 || e == 3) + link_error (); + return e; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-06-20 Jakub Jelinek <ja...@redhat.com> PR c++/86210 * c-common.c (check_nonnull_arg): Use fold_for_warn. Adjust obsolete comment. * g++.dg/warn/Wnonnull4.C: New test. --- gcc/c-family/c-common.c (revision 261811) +++ gcc/c-family/c-common.c (revision 261812) @@ -9249,7 +9249,7 @@ check_nonnull_arg (void *ctx, tree param if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE) return; - if (integer_zerop (param)) + if (integer_zerop (fold_for_warn (param))) warning_at (*ploc, OPT_Wnonnull, "null argument where non-null required " "(argument %lu)", (unsigned long) param_num); } --- gcc/testsuite/g++.dg/warn/Wnonnull4.C (nonexistent) +++ gcc/testsuite/g++.dg/warn/Wnonnull4.C (revision 261812) @@ -0,0 +1,21 @@ +// PR c++/86210 +// { dg-do compile } +// { dg-options "-Wnonnull" } + +void *declared_not_defined (void *p) __attribute__((nonnull)); + +inline void *declared_and_defined (void *p) __attribute__((nonnull)); + +int +main () +{ + int *const p = 0; + declared_not_defined (p); // { dg-warning "null argument where non-null required" } + declared_and_defined (p); // { dg-warning "null argument where non-null required" } +} + +void * +declared_and_defined (void *p) +{ + return p; +}
2018-06-25 Jakub Jelinek <ja...@redhat.com> PR target/84786 * config/i386/sse.md (vshift_count): New mode attr. (<shift_insn><mode>3<mask_name>): Use <vshift_count>N instead of vN as last operand's constraint for VI2_AVX2_AVX512BW shifts. Use YvN instead of vN as last operand's constraint for VI48_AVX2 shifts. * gcc.target/i386/avx512f-pr84786-3.c: New test. --- gcc/config/i386/sse.md.jj 2018-06-22 16:26:34.960232598 +0200 +++ gcc/config/i386/sse.md 2018-06-22 18:04:12.948857074 +0200 @@ -10546,30 +10546,49 @@ (const_string "0"))) (set_attr "mode" "<sseinsnmode>")]) +(define_mode_attr vshift_count + [(V32HI "v") (V16HI "x") (V8HI "x")]) + (define_insn "<shift_insn><mode>3<mask_name>" - [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,v") + [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,v,v") (any_lshift:VI2_AVX2_AVX512BW - (match_operand:VI2_AVX2_AVX512BW 1 "register_operand" "0,v") - (match_operand:DI 2 "nonmemory_operand" "xN,vN")))] + (match_operand:VI2_AVX2_AVX512BW 1 "register_operand" "0,v,v") + (match_operand:DI 2 "nonmemory_operand" "xN,<vshift_count>N,vN")))] "TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>" "@ p<vshift><ssemodesuffix>\t{%2, %0|%0, %2} + vp<vshift><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2} vp<vshift><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}" - [(set_attr "isa" "noavx,avx") + [(set_attr "isa" "noavx,avx,avx512vl") (set_attr "type" "sseishft") (set (attr "length_immediate") (if_then_else (match_operand 2 "const_int_operand") (const_string "1") (const_string "0"))) - (set_attr "prefix_data16" "1,*") - (set_attr "prefix" "orig,vex") + (set_attr "prefix_data16" "1,*,*") + (set_attr "prefix" "orig,vex,vex") + (set_attr "mode" "<sseinsnmode>")]) + +(define_insn "*<shift_insn><mode>3<mask_name>_1" + [(set (match_operand:VI48_AVX2 0 "register_operand" "=v") + (any_lshift:VI48_AVX2 + (match_operand:VI48_AVX2 1 "register_operand" "v") + (match_operand:DI 2 "nonmemory_operand" "vN")))] + "TARGET_AVX512BW && TARGET_AVX512VL" + "vp<vshift><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}" + [(set_attr "type" "sseishft") + (set (attr "length_immediate") + (if_then_else (match_operand 2 "const_int_operand") + (const_string "1") + (const_string "0"))) + (set_attr "prefix" "evex") (set_attr "mode" "<sseinsnmode>")]) (define_insn "<shift_insn><mode>3<mask_name>" [(set (match_operand:VI48_AVX2 0 "register_operand" "=x,x,v") (any_lshift:VI48_AVX2 (match_operand:VI48_AVX2 1 "register_operand" "0,x,v") - (match_operand:DI 2 "nonmemory_operand" "xN,xN,vN")))] + (match_operand:DI 2 "nonmemory_operand" "xN,xN,xN")))] "TARGET_SSE2 && <mask_mode512bit_condition>" "@ p<vshift><ssemodesuffix>\t{%2, %0|%0, %2} --- gcc/testsuite/gcc.target/i386/avx512f-pr84786-3.c.jj 2018-06-22 18:05:06.267926542 +0200 +++ gcc/testsuite/gcc.target/i386/avx512f-pr84786-3.c 2018-06-22 17:39:23.445546062 +0200 @@ -0,0 +1,50 @@ +/* PR target/84786 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mavx512f -mno-avx512vl -O2" } */ + +#include <x86intrin.h> + +__m512i v; +__m128i w; + +__m128i +foo (__m128i x, int y) +{ + __m128i z; +#define A(n) register __m512i zmm##n __asm ("zmm" #n); +#define B A(1) A(2) A(3) A(4) A(5) A(6) A(7) \ + A(8) A(9) A(10) A(11) A(12) A(13) A(14) + B +#undef A +#define A(n) asm volatile ("" : "=v" (zmm##n) : "0" (v)); + B + asm volatile ("" : "=x" (z) : "0" (w)); + x = _mm_srli_epi16 (x, y); + asm volatile ("" : : "x" (z)); +#undef A +#define A(n) asm volatile ("" : : "v" (zmm##n)); + B + return x; +} + +__m256i +bar (__m256i x, int y) +{ + __m128i z; +#undef A +#define A(n) register __m512i zmm##n __asm ("zmm" #n); + B +#undef A +#define A(n) asm volatile ("" : "=v" (zmm##n) : "0" (v)); + B + asm volatile ("" : "=x" (z) : "0" (w)); + x = _mm256_slli_epi16 (x, y); + asm volatile ("" : : "x" (z)); +#undef A +#define A(n) asm volatile ("" : : "v" (zmm##n)); + B + return x; +} + +/* { dg-final { scan-assembler-not "vpsrlw\[\^\n\r]*xmm(1\[6-9]|\[23]\[0-9])" } } */ +/* { dg-final { scan-assembler-not "vpsllw\[\^\n\r]*xmm(1\[6-9]|\[23]\[0-9])" } } */