Hi! I've bootstrapped/regtested the following backports on gcc-8-branch on x86_64-linux and i686-linux and committed.
Jakub
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-08-03 Jason Merrill <ja...@redhat.com> PR c++/86706 * class.c (build_base_path): Use currently_open_class. * g++.dg/template/pr86706.C: New test. --- gcc/cp/class.c (revision 263292) +++ gcc/cp/class.c (revision 263293) @@ -278,6 +278,9 @@ build_base_path (enum tree_code code, probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); if (want_pointer) probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe)); + if (dependent_type_p (probe)) + if (tree open = currently_open_class (probe)) + probe = open; if (code == PLUS_EXPR && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe)) --- gcc/testsuite/g++.dg/template/pr86706.C (nonexistent) +++ gcc/testsuite/g++.dg/template/pr86706.C (revision 263293) @@ -0,0 +1,16 @@ +// PR c++/86706 +// { dg-do compile } + +class A { int b; }; + +template <class, typename> +class C : A { C (); static C *f; }; + +template <class T, typename U> +C<T, U> *C<T, U>::f; + +template <class T, typename U> +C<T, U>::C () +{ + f->b; +}
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-08-08 Jakub Jelinek <ja...@redhat.com> PR c++/86738 * constexpr.c (cxx_eval_binary_expression): For arithmetics involving NULL pointer set *non_constant_p to true. (cxx_eval_component_reference): For dereferencing of a NULL pointer, set *non_constant_p to true and return t. * g++.dg/opt/pr86738.C: New test. --- gcc/cp/constexpr.c (revision 263389) +++ gcc/cp/constexpr.c (revision 263390) @@ -2082,6 +2082,7 @@ cxx_eval_binary_expression (const conste { if (!ctx->quiet) error ("arithmetic involving a null pointer in %qE", lhs); + *non_constant_p = true; return t; } else if (code == POINTER_PLUS_EXPR) @@ -2522,9 +2523,13 @@ cxx_eval_component_reference (const cons lval, non_constant_p, overflow_p); if (INDIRECT_REF_P (whole) - && integer_zerop (TREE_OPERAND (whole, 0)) - && !ctx->quiet) - error ("dereferencing a null pointer in %qE", orig_whole); + && integer_zerop (TREE_OPERAND (whole, 0))) + { + if (!ctx->quiet) + error ("dereferencing a null pointer in %qE", orig_whole); + *non_constant_p = true; + return t; + } if (TREE_CODE (whole) == PTRMEM_CST) whole = cplus_expand_constant (whole); --- gcc/testsuite/g++.dg/opt/pr86738.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr86738.C (revision 263390) @@ -0,0 +1,12 @@ +// PR c++/86738 +// { dg-do compile } + +struct S { int s; }; +unsigned char a[20]; +unsigned char *p = &a[(__UINTPTR_TYPE__) &((S *) 0)->s]; + +void +foo () +{ + __builtin_memcpy (&a[15], &a[(__UINTPTR_TYPE__) &((S *) 0)->s], 2); +}
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-08-08 Jakub Jelinek <ja...@redhat.com> PR c++/86836 * pt.c (tsubst_expr): For structured bindings, call tsubst_decomp_names before tsubst_init, not after it. * g++.dg/cpp1z/decomp46.C: New test. --- gcc/cp/pt.c (revision 263390) +++ gcc/cp/pt.c (revision 263391) @@ -16740,7 +16740,17 @@ tsubst_expr (tree t, tree args, tsubst_f else { int const_init = false; + unsigned int cnt = 0; + tree first = NULL_TREE, ndecl = error_mark_node; maybe_push_decl (decl); + + if (VAR_P (decl) + && DECL_DECOMPOSITION_P (decl) + && TREE_TYPE (pattern_decl) != error_mark_node) + ndecl = tsubst_decomp_names (decl, pattern_decl, args, + complain, in_decl, &first, + &cnt); + if (VAR_P (decl) && DECL_PRETTY_FUNCTION_P (decl)) { @@ -16756,23 +16766,14 @@ tsubst_expr (tree t, tree args, tsubst_f if (VAR_P (decl)) const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (pattern_decl)); - if (VAR_P (decl) - && DECL_DECOMPOSITION_P (decl) - && TREE_TYPE (pattern_decl) != error_mark_node) - { - unsigned int cnt; - tree first; - tree ndecl - = tsubst_decomp_names (decl, pattern_decl, args, - complain, in_decl, &first, &cnt); - if (ndecl != error_mark_node) - cp_maybe_mangle_decomp (ndecl, first, cnt); - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); - if (ndecl != error_mark_node) - cp_finish_decomp (ndecl, first, cnt); - } - else - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + + if (ndecl != error_mark_node) + cp_maybe_mangle_decomp (ndecl, first, cnt); + + cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + + if (ndecl != error_mark_node) + cp_finish_decomp (ndecl, first, cnt); } } } --- gcc/testsuite/g++.dg/cpp1z/decomp46.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp46.C (revision 263391) @@ -0,0 +1,25 @@ +// PR c++/86836 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { + int operator*(); + void operator++(); + bool operator!=(A); +}; +template <typename> class map { +public: + A begin(); + A end(); +}; + +template <typename T> void mergemap(map<T> orig, map<T> toadd) { + for (auto p : toadd) + auto [orig] = orig; // { dg-error "use of 'orig' before deduction of 'auto'" } +} // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + +int +main() { + map<double> x, y; + mergemap(x, y); +}
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-08-11 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/86835 * tree-ssa-math-opts.c (insert_reciprocals): Even when inserting new_stmt after def_gsi, make sure to insert new_square_stmt after that stmt, not 2 stmts before it. * gcc.dg/pr86835.c: New test. --- gcc/tree-ssa-math-opts.c (revision 263486) +++ gcc/tree-ssa-math-opts.c (revision 263487) @@ -422,6 +422,8 @@ insert_reciprocals (gimple_stmt_iterator gsi_next (&gsi); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + if (should_insert_square_recip) + gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT); } else if (def_gsi && occ->bb == def_gsi->bb) { @@ -429,21 +431,19 @@ insert_reciprocals (gimple_stmt_iterator never happen if the definition statement can throw, because in that case the sole successor of the statement's basic block will dominate all the uses as well. */ - gsi = *def_gsi; gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT); + if (should_insert_square_recip) + gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT); } else { /* Case 3: insert in a basic block not containing defs/uses. */ gsi = gsi_after_labels (occ->bb); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + if (should_insert_square_recip) + gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT); } - /* Regardless of which case the reciprocal as inserted in, - we insert the square immediately after the reciprocal. */ - if (should_insert_square_recip) - gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT); - reciprocal_stats.rdivs_inserted++; occ->recip_def_stmt = new_stmt; --- gcc/testsuite/gcc.dg/pr86835.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr86835.c (revision 263487) @@ -0,0 +1,29 @@ +/* PR tree-optimization/86835 */ +/* { dg-do run } */ +/* { dg-options "-O2 -ffast-math -Wuninitialized" } */ + +__attribute__((noipa)) void +foo (int n, double *x, double *y) +{ /* { dg-bogus "is used uninitialized in this function" "" { target *-*-* } 0 } */ + int i; + double b = y[4]; + for (i = 0; i < n; ++i) + y[3] += __builtin_sin (x[i] / b); + y[0] /= b; + y[1] /= b * b; + y[2] /= b; +} + +int +main () +{ + double y[] = { 16.0, 64.0, 128.0, 0.0, 2.0 }; + foo (0, y, y); + if (__builtin_fabs (y[0] - 8.0) > 0.0001 + || __builtin_fabs (y[1] - 16.0) > 0.0001 + || __builtin_fabs (y[2] - 64.0) > 0.0001 + || y[3] != 0.0 + || y[4] != 2.0) + __builtin_abort (); + return 0; +}
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-08-29 Jakub Jelinek <ja...@redhat.com> PR c++/87095 * decl.c (begin_destructor_body): If current_class_type has virtual bases and the primary base is nearly empty virtual base, voidify clearing of vptr and make it conditional on in-charge argument. * g++.dg/ubsan/vptr-13.C: New test. --- gcc/cp/decl.c (revision 263966) +++ gcc/cp/decl.c (revision 263967) @@ -15698,6 +15698,18 @@ begin_destructor_body (void) tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR, vtbl, tf_warning_or_error); + /* If the vptr is shared with some virtual nearly empty base, + don't clear it if not in charge, the dtor of the virtual + nearly empty base will do that later. */ + if (CLASSTYPE_VBASECLASSES (current_class_type) + && CLASSTYPE_PRIMARY_BINFO (current_class_type) + && BINFO_VIRTUAL_P + (CLASSTYPE_PRIMARY_BINFO (current_class_type))) + { + stmt = convert_to_void (stmt, ICV_STATEMENT, + tf_warning_or_error); + stmt = build_if_in_charge (stmt); + } finish_decl_cleanup (NULL_TREE, stmt); } else --- gcc/testsuite/g++.dg/ubsan/vptr-13.C (nonexistent) +++ gcc/testsuite/g++.dg/ubsan/vptr-13.C (revision 263967) @@ -0,0 +1,19 @@ +// PR c++/87095 +// { dg-do run } +// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" } + +struct A +{ + virtual ~A () {} +}; + +struct B : virtual A {}; + +struct C : B {}; + +int +main () +{ + C c; + return 0; +}
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-08-31 Jakub Jelinek <ja...@redhat.com> PR middle-end/87138 * expmed.c (expand_mult_const): Use immed_wide_int_const instead of gen_int_mode. Formatting fixes. * gcc.target/i386/avx512bw-pr87138.c: New test. --- gcc/expmed.c (revision 264008) +++ gcc/expmed.c (revision 264009) @@ -3347,19 +3347,21 @@ expand_mult_const (machine_mode mode, rt /* Write a REG_EQUAL note on the last insn so that we can cse multiplication sequences. Note that if ACCUM is a SUBREG, we've set the inner register and must properly indicate that. */ - tem = op0, nmode = mode; - accum_inner = accum; - if (GET_CODE (accum) == SUBREG) + tem = op0, nmode = mode; + accum_inner = accum; + if (GET_CODE (accum) == SUBREG) { accum_inner = SUBREG_REG (accum); nmode = GET_MODE (accum_inner); tem = gen_lowpart (nmode, op0); } - insn = get_last_insn (); - set_dst_reg_note (insn, REG_EQUAL, - gen_rtx_MULT (nmode, tem, - gen_int_mode (val_so_far, nmode)), + insn = get_last_insn (); + wide_int wval_so_far + = wi::uhwi (val_so_far, + GET_MODE_PRECISION (as_a <scalar_mode> (nmode))); + rtx c = immed_wide_int_const (wval_so_far, nmode); + set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c), accum_inner); } } --- gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/avx512bw-pr87138.c (revision 264009) @@ -0,0 +1,29 @@ +/* PR middle-end/87138 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O -fno-tree-fre -mavx512bw -mtune=k8" } */ +/* { dg-require-effective-target avx512bw } */ + +#include "avx512bw-check.h" + +typedef int U __attribute__ ((vector_size (64))); +typedef __int128 V __attribute__ ((vector_size (64))); +V g, i; + +static inline void +foo (unsigned h, V j, U k, V n) +{ + k /= h; + __builtin_memmove (&h, &n, 1); + n[j[1]] *= 0x7FFFFFFFFFFFFFFF; + j[k[5]] = 0; + g = n; + i = h + j + n; +} + +void +avx512bw_test () +{ + foo (~0, (V) { }, (U) { 5 }, (V) { 3 }); + if (g[0] != (__int128) 3 * 0x7FFFFFFFFFFFFFFF) + abort (); +}
2018-09-05 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-09-04 Jakub Jelinek <ja...@redhat.com> PR target/87198 * common/config/i386/i386-common.c (OPTION_MASK_ISA_XSAVEOPT_SET, OPTION_MASK_ISA_XSAVES_SET, OPTION_MASK_ISA_XSAVEC_SET): Use OPTION_MASK_ISA_XSAVE_SET instead of OPTION_MASK_ISA_XSAVE. (OPTION_MASK_ISA_XSAVE_UNSET): Add OPTION_MASK_ISA_XSAVES_UNSET and OPTION_MASK_ISA_XSAVEC_UNSET. * gcc.target/i386/pr87198.c: New test. --- gcc/common/config/i386/i386-common.c (revision 264087) +++ gcc/common/config/i386/i386-common.c (revision 264088) @@ -59,7 +59,7 @@ along with GCC; see the file COPYING3. #define OPTION_MASK_ISA_FXSR_SET OPTION_MASK_ISA_FXSR #define OPTION_MASK_ISA_XSAVE_SET OPTION_MASK_ISA_XSAVE #define OPTION_MASK_ISA_XSAVEOPT_SET \ - (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE) + (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_AVX512F_SET \ (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX2_SET) #define OPTION_MASK_ISA_AVX512CD_SET \ @@ -95,9 +95,9 @@ along with GCC; see the file COPYING3. #define OPTION_MASK_ISA_PREFETCHWT1_SET OPTION_MASK_ISA_PREFETCHWT1 #define OPTION_MASK_ISA_CLFLUSHOPT_SET OPTION_MASK_ISA_CLFLUSHOPT #define OPTION_MASK_ISA_XSAVES_SET \ - (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE) + (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_XSAVEC_SET \ - (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE) + (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_CLWB_SET OPTION_MASK_ISA_CLWB /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same @@ -185,7 +185,8 @@ along with GCC; see the file COPYING3. #define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA #define OPTION_MASK_ISA_FXSR_UNSET OPTION_MASK_ISA_FXSR #define OPTION_MASK_ISA_XSAVE_UNSET \ - (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET) + (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET \ + | OPTION_MASK_ISA_XSAVES_UNSET | OPTION_MASK_ISA_XSAVEC_UNSET) #define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT #define OPTION_MASK_ISA_AVX2_UNSET \ (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET) --- gcc/testsuite/gcc.target/i386/pr87198.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr87198.c (revision 264088) @@ -0,0 +1,13 @@ +/* PR target/87198 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mxsavec -mno-xsave" } */ + +#include <x86intrin.h> + +void +test_xsavec (void *__A, long long __B) +{ + _xsavec (__A, __B); +} + +/* { dg-error "target specific option mismatch" "" { target *-*-* } 0 } */