Hi! I've backported following 61 trunk commits to 7.x branch (2 patches contain more than one commit), bootstrapped/regtested them on x86_64-linux and i686-linux and committed to 7.x branch.
Jakub
2018-06-22 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) @@ -17318,14 +17318,14 @@ 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 (TREE_CODE (templ) == SCOPE_REF) { tree name = TREE_OPERAND (templ, 1); tree tid = lookup_template_function (name, targs); TREE_OPERAND (templ, 1) = tid; - return templ; + RETURN (templ); } if (variable_template_p (templ)) @@ -17401,6 +17401,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)); } @@ -17549,7 +17551,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: --- 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-22 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-08 Jason Merrill <ja...@redhat.com> Jakub Jelinek <ja...@redhat.com> PR c++/80598 * call.c (build_over_call): In templates set TREE_USED (first_fn) when not calling mark_used for the benefit of -Wunused-function warning. * g++.dg/warn/Wunused-function4.C: New test. --- gcc/cp/call.c (revision 258369) +++ gcc/cp/call.c (revision 258370) @@ -7634,6 +7634,10 @@ build_over_call (struct z_candidate *can if (undeduced_auto_decl (fn)) mark_used (fn, complain); + else + /* Otherwise set TREE_USED for the benefit of -Wunused-function. + See PR80598. */ + TREE_USED (fn) = 1; return_type = TREE_TYPE (TREE_TYPE (fn)); nargs = vec_safe_length (args); --- gcc/testsuite/g++.dg/warn/Wunused-function4.C (nonexistent) +++ gcc/testsuite/g++.dg/warn/Wunused-function4.C (revision 258370) @@ -0,0 +1,21 @@ +// PR c++/80598 +// { dg-do compile } +// { dg-options "-Wunused-function" } + +static void +foo () // { dg-bogus "defined but not used" } +{ +} + +static void +bar () // { dg-warning "defined but not used" } +{ +} + +template <class T> +int +baz (T x) +{ + foo (); + return 0; +}
2018-06-22 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-22 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) @@ -7144,7 +7144,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); } /* Build up a real lvalue-to-rvalue conversion in case the copy constructor is trivial but not callable. */ @@ -7935,7 +7935,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]); + } warned_p = check_function_arguments (input_location, fn, 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-13 Jakub Jelinek <ja...@redhat.com> PR target/84786 * config/i386/sse.md (sse2_loadhpd): Use Yv constraint rather than v on the last operand. * gcc.target/i386/avx512f-pr84786-1.c: New test. * gcc.target/i386/avx512f-pr84786-2.c: New test. --- gcc/config/i386/sse.md (revision 258474) +++ gcc/config/i386/sse.md (revision 258475) @@ -9022,14 +9022,14 @@ (define_expand "sse2_loadhpd_exp" ;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_loadhpd" [(set (match_operand:V2DF 0 "nonimmediate_operand" - "=x,v,x,v,o,o ,o") + "=x,v,x,v ,o,o ,o") (vec_concat:V2DF (vec_select:DF (match_operand:V2DF 1 "nonimmediate_operand" - " 0,v,0,v,0,0 ,0") + " 0,v,0,v ,0,0 ,0") (parallel [(const_int 0)])) (match_operand:DF 2 "nonimmediate_operand" - " m,m,x,v,x,*f,r")))] + " m,m,x,Yv,x,*f,r")))] "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ movhpd\t{%2, %0|%0, %2} --- gcc/testsuite/gcc.target/i386/avx512f-pr84786-1.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/avx512f-pr84786-1.c (revision 258475) @@ -0,0 +1,25 @@ +/* PR target/84786 */ +/* { dg-do run { target { ! ia32 } } } */ +/* { dg-options "-mavx512f -mno-avx512vl -O2" } */ +/* { dg-require-effective-target avx512f } */ + +#include "avx512f-check.h" + +typedef double V __attribute__((vector_size (16))); + +__attribute__((noinline, noclone)) V +foo (V x, double y) +{ + register double z __asm ("xmm18"); + asm volatile ("" : "=v" (z) : "0" (y)); + x[1] = z; + return x; +} + +static void +avx512f_test (void) +{ + V a = foo ((V) { 1.0, 2.0 }, 3.0); + if (a[0] != 1.0 || a[1] != 3.0) + abort (); +} --- gcc/testsuite/gcc.target/i386/avx512f-pr84786-2.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/avx512f-pr84786-2.c (revision 258475) @@ -0,0 +1,16 @@ +/* PR target/84786 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mavx512f -mno-avx512vl -O2" } */ + +typedef double V __attribute__((vector_size (16))); + +__attribute__((noinline, noclone)) V +foo (V x, double y) +{ + register double z __asm ("xmm18"); + asm volatile ("" : "=v" (z) : "0" (y)); + x[1] = z; + return x; +} + +/* { dg-final { scan-assembler-not "vunpcklpd\[\^\n\r]*xmm(1\[6-9]|\[23]\[0-9])" } } */
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-13 Jakub Jelinek <ja...@redhat.com> PR target/84827 * config/i386/i386.md (round<mode>2): For 387 fancy math, disable pattern if -ftrapping-math -fno-fp-int-builtin-inexact. * gcc.target/i386/pr84827.c: New test. --- gcc/config/i386/i386.md (revision 258476) +++ gcc/config/i386/i386.md (revision 258477) @@ -16311,7 +16311,8 @@ (define_expand "round<mode>2" "(TARGET_USE_FANCY_MATH_387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) - && flag_unsafe_math_optimizations) + && flag_unsafe_math_optimizations + && (flag_fp_int_builtin_inexact || !flag_trapping_math)) || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && !flag_trapping_math && !flag_rounding_math)" { --- gcc/testsuite/gcc.target/i386/pr84827.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr84827.c (revision 258477) @@ -0,0 +1,21 @@ +/* PR target/84827 */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fno-fp-int-builtin-inexact -ftrapping-math -fno-associative-math -mfpmath=387" } */ + +double +f1 (double a) +{ + return __builtin_round (a); +} + +float +f2 (float a) +{ + return __builtin_roundf (a); +} + +long double +f3 (long double a) +{ + return __builtin_roundl (a); +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-13 Jakub Jelinek <ja...@redhat.com> PR middle-end/84834 * match.pd ((A & C) != 0 ? D : 0): Use INTEGER_CST@2 instead of integer_pow2p@2 and test integer_pow2p in condition. (A < 0 ? C : 0): Similarly for @1. * gcc.dg/pr84834.c: New test. --- gcc/match.pd (revision 258478) +++ gcc/match.pd (revision 258479) @@ -2789,15 +2789,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (cond (ne (bit_and @0 integer_pow2p@1) integer_zerop) - integer_pow2p@2 integer_zerop) - (with { - int shift = wi::exact_log2 (@2) - wi::exact_log2 (@1); - } - (if (shift > 0) - (bit_and - (lshift (convert @0) { build_int_cst (integer_type_node, shift); }) @2) - (bit_and - (convert (rshift @0 { build_int_cst (integer_type_node, -shift); })) @2)))) + INTEGER_CST@2 integer_zerop) + (if (integer_pow2p (@2)) + (with { + int shift = wi::exact_log2 (@2) - wi::exact_log2 (@1); + } + (if (shift > 0) + (bit_and + (lshift (convert @0) { build_int_cst (integer_type_node, shift); }) @2) + (bit_and + (convert (rshift @0 { build_int_cst (integer_type_node, -shift); })) + @2))))) /* If we have (A & C) != 0 where C is the sign bit of A, convert this into A < 0. Similarly for (A & C) == 0 into A >= 0. */ @@ -2818,8 +2820,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (cond (lt @0 integer_zerop) - integer_pow2p@1 integer_zerop) - (if (!TYPE_UNSIGNED (TREE_TYPE (@0))) + INTEGER_CST@1 integer_zerop) + (if (integer_pow2p (@1) + && !TYPE_UNSIGNED (TREE_TYPE (@0))) (with { int shift = element_precision (@0) - wi::exact_log2 (@1) - 1; } --- gcc/testsuite/gcc.dg/pr84834.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84834.c (revision 258479) @@ -0,0 +1,15 @@ +/* PR middle-end/84834 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +_Complex int +foo (int a) +{ + return a < 0; +} + +_Complex int +bar (int a) +{ + return (a & 8) ? (_Complex int) 16 : (_Complex int) 0; +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-15 Jakub Jelinek <ja...@redhat.com> PR c/84853 * c-typeck.c (build_binary_op) <case RSHIFT_EXPR, case LSHIFT_EXPR>: If code1 is INTEGER_TYPE, only allow code0 VECTOR_TYPE if it has INTEGER_TYPE element type. * gcc.dg/pr84853.c: New test. --- gcc/c/c-typeck.c (revision 258549) +++ gcc/c/c-typeck.c (revision 258550) @@ -11150,7 +11150,8 @@ build_binary_op (location_t location, en converted = 1; } else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE - || code0 == VECTOR_TYPE) + || (code0 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11207,7 +11208,8 @@ build_binary_op (location_t location, en converted = 1; } else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE - || code0 == VECTOR_TYPE) + || (code0 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)) && code1 == INTEGER_TYPE) { doing_shift = true; --- gcc/testsuite/gcc.dg/pr84853.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84853.c (revision 258550) @@ -0,0 +1,19 @@ +/* PR c/84853 */ +/* { dg-do compile } */ + +typedef float V __attribute__((__vector_size__ (16))); +typedef int W __attribute__((__vector_size__ (16))); + +void +foo (int x, V *y, V *z, W *w) +{ + *y = *y << x; /* { dg-error "invalid operands to binary <<" } */ + *z = *z << *w; /* { dg-error "invalid operands to binary <<" } */ +} + +void +bar (int x, V *y, V *z, W *w) +{ + *y = *y >> x; /* { dg-error "invalid operands to binary >>" } */ + *z = *z >> *w; /* { dg-error "invalid operands to binary >>" } */ +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-15 Jakub Jelinek <ja...@redhat.com> PR target/84860 * optabs.c (emit_conditional_move): Pass address of cmode's copy rather than address of cmode as last argument to prepare_cmp_insn. * gcc.c-torture/compile/pr84860.c: New test. --- gcc/optabs.c (revision 258551) +++ gcc/optabs.c (revision 258552) @@ -4345,9 +4345,10 @@ emit_conditional_move (rtx target, enum save_pending_stack_adjust (&save); last = get_last_insn (); do_pending_stack_adjust (); + machine_mode cmpmode = cmode; prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), GET_CODE (comparison), NULL_RTX, unsignedp, - OPTAB_WIDEN, &comparison, &cmode); + OPTAB_WIDEN, &comparison, &cmpmode); if (comparison) { struct expand_operand ops[4]; --- gcc/testsuite/gcc.c-torture/compile/pr84860.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr84860.c (revision 258552) @@ -0,0 +1,11 @@ +/* PR target/84860 */ + +void +foo (int x, int y) +{ + while (x < 1) + { + x = y; + y = ((float)1 / 0) ? 2 : 0; + } +}
2018-06-22 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) @@ -10448,7 +10448,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; @@ -10456,7 +10456,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. */ @@ -11271,8 +11271,18 @@ grokdeclarator (const cp_declarator *dec explicitp = 2; } - 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 @@ -12799,7 +12809,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-22 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-16 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/84841 * tree-ssa-reassoc.c (INTEGER_CONST_TYPE): Change to 1 << 4 from 1 << 3. (FLOAT_ONE_CONST_TYPE): Define. (constant_type): Return FLOAT_ONE_CONST_TYPE for -1.0 and 1.0. (sort_by_operand_rank): Put entries with higher constant_type last rather than first to match comments. * gcc.dg/pr84841.c: New test. --- gcc/tree-ssa-reassoc.c (revision 258585) +++ gcc/tree-ssa-reassoc.c (revision 258586) @@ -470,7 +470,8 @@ get_rank (tree e) /* We want integer ones to end up last no matter what, since they are the ones we can do the most with. */ -#define INTEGER_CONST_TYPE 1 << 3 +#define INTEGER_CONST_TYPE 1 << 4 +#define FLOAT_ONE_CONST_TYPE 1 << 3 #define FLOAT_CONST_TYPE 1 << 2 #define OTHER_CONST_TYPE 1 << 1 @@ -482,7 +483,14 @@ constant_type (tree t) if (INTEGRAL_TYPE_P (TREE_TYPE (t))) return INTEGER_CONST_TYPE; else if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (t))) - return FLOAT_CONST_TYPE; + { + /* Sort -1.0 and 1.0 constants last, while in some cases + const_binop can't optimize some inexact operations, multiplication + by -1.0 or 1.0 can be always merged with others. */ + if (real_onep (t) || real_minus_onep (t)) + return FLOAT_ONE_CONST_TYPE; + return FLOAT_CONST_TYPE; + } else return OTHER_CONST_TYPE; } @@ -501,7 +509,7 @@ sort_by_operand_rank (const void *pa, co if (oeb->rank == 0 && oea->rank == 0) { if (constant_type (oeb->op) != constant_type (oea->op)) - return constant_type (oeb->op) - constant_type (oea->op); + return constant_type (oea->op) - constant_type (oeb->op); else /* To make sorting result stable, we use unique IDs to determine order. */ --- gcc/testsuite/gcc.dg/pr84841.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84841.c (revision 258586) @@ -0,0 +1,9 @@ +/* PR tree-optimization/84841 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fassociative-math -frounding-math -fno-signed-zeros -fno-trapping-math -fno-tree-forwprop" } */ + +double +foo (double x) +{ + return -x * 0.1 * 0.1; +}
2018-06-22 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-22 Jakub Jelinek <ja...@redhat.com> PR sanitizer/85018 * dwarf2asm.c (dw2_output_indirect_constant_1): Set DECL_INITIAL (decl) to decl at the end. * varasm.c (use_blocks_for_decl_p): Revert the 2018-03-20 change, adjust the comment. 2018-03-20 Jakub Jelinek <ja...@redhat.com> PR target/84990 * dwarf2asm.c (dw2_output_indirect_constant_1): Temporarily turn off flag_section_anchors. * varasm.c (use_blocks_for_decl_p): Remove hack for dw2_force_const_mem. 2018-03-19 Jakub Jelinek <ja...@redhat.com> PR sanitizer/78651 * dwarf2asm.c: Include fold-const.c. (dw2_output_indirect_constant_1): Set DECL_INITIAL (decl) to ADDR_EXPR of decl rather than decl itself. 2018-03-19 Maxim Ostapenko <m.ostape...@samsung.com> PR sanitizer/78651 * dwarf2asm.c (dw2_output_indirect_constant_1): Disable ASan before calling assemble_variable. * g++.dg/asan/pr78651.C: New test. --- gcc/dwarf2asm.c (revision 258657) +++ gcc/dwarf2asm.c (revision 258757) @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. #include "dwarf2.h" #include "function.h" #include "emit-rtl.h" +#include "fold-const.h" #ifndef XCOFF_DEBUGGING_INFO #define XCOFF_DEBUGGING_INFO 0 @@ -925,7 +926,7 @@ dw2_output_indirect_constant_1 (const ch SET_DECL_ASSEMBLER_NAME (decl, id); DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; - DECL_INITIAL (decl) = decl; + DECL_INITIAL (decl) = build_fold_addr_expr (decl); TREE_READONLY (decl) = 1; TREE_STATIC (decl) = 1; @@ -938,8 +939,23 @@ dw2_output_indirect_constant_1 (const ch } sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym); + /* Disable ASan for decl because redzones cause ABI breakage between GCC and + libstdc++ for `.LDFCM*' variables. See PR 78651 for details. */ + unsigned int save_flag_sanitize = flag_sanitize; + flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS + | SANITIZE_KERNEL_ADDRESS); + /* And also temporarily disable -fsection-anchors. These indirect constants + are never referenced from code, so it doesn't make any sense to aggregate + them in blocks. */ + int save_flag_section_anchors = flag_section_anchors; + flag_section_anchors = 0; assemble_variable (decl, 1, 1, 1); + flag_section_anchors = save_flag_section_anchors; + flag_sanitize = save_flag_sanitize; assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1); + /* The following is a hack recognized by use_blocks_for_decl_p to disable + section anchor handling of the decl. */ + DECL_INITIAL (decl) = decl; return 0; } --- gcc/varasm.c (revision 258680) +++ gcc/varasm.c (revision 258757) @@ -1241,10 +1241,9 @@ use_blocks_for_decl_p (tree decl) if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL) return false; - /* Detect decls created by dw2_force_const_mem. Such decls are - special because DECL_INITIAL doesn't specify the decl's true value. - dw2_output_indirect_constants will instead call assemble_variable - with dont_output_data set to 1 and then print the contents itself. */ + /* DECL_INITIAL (decl) set to decl is a hack used for some decls that + are never used from code directly and we never want object block handling + for those. */ if (DECL_INITIAL (decl) == decl) return false; --- gcc/testsuite/g++.dg/asan/pr78651.C (nonexistent) +++ gcc/testsuite/g++.dg/asan/pr78651.C (revision 258658) @@ -0,0 +1,26 @@ +// PR sanitizer/78651 +// { dg-do run } +// { dg-additional-options "-fpic" { target fpic } } + +struct A { }; + +namespace { + +void thisThrows () { + throw A(); +} + +struct SomeRandomType {}; +} + +int main() { + try { + thisThrows(); + } + catch (SomeRandomType) { + throw; + } + catch (A) { + } + return 0; +}
2018-06-22 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-21 Jakub Jelinek <ja...@redhat.com> PR c++/84961 * cp-tree.h (genericize_compound_lvalue): Declare. * typeck.c (genericize_compound_lvalue): New function. (unary_complex_lvalue, cp_build_modify_expr): Use it. * semantics.c (finish_asm_stmt): Replace MODIFY_EXPR, PREINCREMENT_EXPR and PREDECREMENT_EXPR in output and "m" constrained input operands with COMPOUND_EXPR. Call cxx_mark_addressable on the rightmost COMPOUND_EXPR operand. * c-c++-common/pr43690.c: Don't expect errors on "m" (--x) and "m" (++x) in C++. * g++.dg/torture/pr84961-1.C: New test. * g++.dg/torture/pr84961-2.C: New test. --- gcc/cp/typeck.c (revision 258740) +++ gcc/cp/typeck.c (revision 258741) @@ -6357,6 +6357,25 @@ build_unary_op (location_t /*location*/, return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error); } +/* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR, + so that it is a valid lvalue even for GENERIC by replacing + (lhs = rhs) with ((lhs = rhs), lhs) + (--lhs) with ((--lhs), lhs) + (++lhs) with ((++lhs), lhs) + and if lhs has side-effects, calling cp_stabilize_reference on it, so + that it can be evaluated multiple times. */ + +tree +genericize_compound_lvalue (tree lvalue) +{ + if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0))) + lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue), + cp_stabilize_reference (TREE_OPERAND (lvalue, 0)), + TREE_OPERAND (lvalue, 1)); + return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)), + lvalue, TREE_OPERAND (lvalue, 0)); +} + /* Apply unary lvalue-demanding operator CODE to the expression ARG for certain kinds of expressions which are not really lvalues but which we can accept as lvalues. @@ -6391,17 +6410,7 @@ unary_complex_lvalue (enum tree_code cod if (TREE_CODE (arg) == MODIFY_EXPR || TREE_CODE (arg) == PREINCREMENT_EXPR || TREE_CODE (arg) == PREDECREMENT_EXPR) - { - tree lvalue = TREE_OPERAND (arg, 0); - if (TREE_SIDE_EFFECTS (lvalue)) - { - lvalue = cp_stabilize_reference (lvalue); - arg = build2 (TREE_CODE (arg), TREE_TYPE (arg), - lvalue, TREE_OPERAND (arg, 1)); - } - return unary_complex_lvalue - (code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue)); - } + return unary_complex_lvalue (code, genericize_compound_lvalue (arg)); if (code != ADDR_EXPR) return NULL_TREE; @@ -7887,11 +7896,7 @@ cp_build_modify_expr (location_t loc, tr case PREINCREMENT_EXPR: if (compound_side_effects_p) newrhs = rhs = stabilize_expr (rhs, &preeval); - if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) - lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs), - cp_stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); - lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0)); + lhs = genericize_compound_lvalue (lhs); maybe_add_compound: /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5; and looked through the COMPOUND_EXPRs, readd them now around @@ -7914,11 +7919,7 @@ cp_build_modify_expr (location_t loc, tr case MODIFY_EXPR: if (compound_side_effects_p) newrhs = rhs = stabilize_expr (rhs, &preeval); - if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) - lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs), - cp_stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); - lhs = build2 (COMPOUND_EXPR, lhstype, lhs, TREE_OPERAND (lhs, 0)); + lhs = genericize_compound_lvalue (lhs); goto maybe_add_compound; case MIN_EXPR: --- gcc/cp/semantics.c (revision 258740) +++ gcc/cp/semantics.c (revision 258741) @@ -1512,6 +1512,21 @@ finish_asm_stmt (int volatile_p, tree st && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand))))) cxx_readonly_error (operand, lv_asm); + tree *op = &operand; + while (TREE_CODE (*op) == COMPOUND_EXPR) + op = &TREE_OPERAND (*op, 1); + switch (TREE_CODE (*op)) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case MODIFY_EXPR: + *op = genericize_compound_lvalue (*op); + op = &TREE_OPERAND (*op, 1); + break; + default: + break; + } + constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); oconstraints[i] = constraint; @@ -1520,7 +1535,7 @@ finish_asm_stmt (int volatile_p, tree st { /* If the operand is going to end up in memory, mark it addressable. */ - if (!allows_reg && !cxx_mark_addressable (operand)) + if (!allows_reg && !cxx_mark_addressable (*op)) operand = error_mark_node; } else @@ -1562,7 +1577,23 @@ finish_asm_stmt (int volatile_p, tree st /* Strip the nops as we allow this case. FIXME, this really should be rejected or made deprecated. */ STRIP_NOPS (operand); - if (!cxx_mark_addressable (operand)) + + tree *op = &operand; + while (TREE_CODE (*op) == COMPOUND_EXPR) + op = &TREE_OPERAND (*op, 1); + switch (TREE_CODE (*op)) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case MODIFY_EXPR: + *op = genericize_compound_lvalue (*op); + op = &TREE_OPERAND (*op, 1); + break; + default: + break; + } + + if (!cxx_mark_addressable (*op)) operand = error_mark_node; } else if (!allows_reg && !allows_mem) --- gcc/cp/cp-tree.h (revision 258740) +++ gcc/cp/cp-tree.h (revision 258741) @@ -7145,6 +7145,7 @@ extern tree cp_build_addressof (locati extern tree cp_build_addr_expr (tree, tsubst_flags_t); extern tree cp_build_unary_op (enum tree_code, tree, bool, tsubst_flags_t); +extern tree genericize_compound_lvalue (tree); extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (location_t, tree, tree, tree, tsubst_flags_t); --- gcc/testsuite/g++.dg/torture/pr84961-1.C (nonexistent) +++ gcc/testsuite/g++.dg/torture/pr84961-1.C (revision 258741) @@ -0,0 +1,24 @@ +// PR c++/84961 +// { dg-do compile } + +short a; +volatile int b; +int c, d; + +void +foo () +{ + asm volatile ("" : "=r" (b = a)); +} + +void +bar () +{ + asm volatile ("" : "=r" (++c, ++d, b = a)); +} + +void +baz () +{ + asm volatile ("" : "=r" (--b)); +} --- gcc/testsuite/g++.dg/torture/pr84961-2.C (nonexistent) +++ gcc/testsuite/g++.dg/torture/pr84961-2.C (revision 258741) @@ -0,0 +1,24 @@ +// PR c++/84961 +// { dg-do compile } + +short a; +volatile int b; +int c, d; + +void +foo () +{ + asm volatile ("" : : "m" (b = a)); +} + +void +bar () +{ + asm volatile ("" : : "m" (++c, ++d, b = a)); +} + +void +baz () +{ + asm volatile ("" : : "m" (--b)); +} --- gcc/testsuite/c-c++-common/pr43690.c (revision 258740) +++ gcc/testsuite/c-c++-common/pr43690.c (revision 258741) @@ -6,8 +6,8 @@ void foo (char *x) { asm ("" : : "m" (x++)); /* { dg-error "is not directly addressable" } */ - asm ("" : : "m" (++x)); /* { dg-error "is not directly addressable" } */ + asm ("" : : "m" (++x)); /* { dg-error "is not directly addressable" "" { target c } } */ asm ("" : : "m" (x--)); /* { dg-error "is not directly addressable" } */ - asm ("" : : "m" (--x)); /* { dg-error "is not directly addressable" } */ + asm ("" : : "m" (--x)); /* { dg-error "is not directly addressable" "" { target c } } */ asm ("" : : "m" (x + 1)); /* { dg-error "is not directly addressable" } */ }
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-21 Jakub Jelinek <ja...@redhat.com> PR c/84999 * c-typeck.c (build_binary_op): If c_common_type_for_size fails when building vector comparison, diagnose it and return error_mark_node. * c-c++-common/pr84999.c: New test. --- gcc/c/c-typeck.c (revision 258746) +++ gcc/c/c-typeck.c (revision 258747) @@ -11301,6 +11301,13 @@ build_binary_op (location_t location, en /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); + if (!intt) + { + error_at (location, "could not find an integer type " + "of the same size as %qT", + TREE_TYPE (type0)); + return error_mark_node; + } result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; @@ -11460,6 +11467,13 @@ build_binary_op (location_t location, en /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); + if (!intt) + { + error_at (location, "could not find an integer type " + "of the same size as %qT", + TREE_TYPE (type0)); + return error_mark_node; + } result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; --- gcc/testsuite/c-c++-common/pr84999.c (nonexistent) +++ gcc/testsuite/c-c++-common/pr84999.c (revision 258747) @@ -0,0 +1,12 @@ +/* PR c/84999 */ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "" } */ + +typedef __float128 V __attribute__ ((__vector_size__ (2 * sizeof (__float128)))); +V a; +typeof (a != 0) b; /* { dg-error "could not find an integer type of the same size as" "" { target ia32 } } */ +typeof (a == 0) c; /* { dg-error "could not find an integer type of the same size as" "" { target ia32 } } */ +typeof (a < 0) d; /* { dg-error "could not find an integer type of the same size as" "" { target ia32 } } */ +typeof (a <= 0) e; /* { dg-error "could not find an integer type of the same size as" "" { target ia32 } } */ +typeof (a > 0) f; /* { dg-error "could not find an integer type of the same size as" "" { target ia32 } } */ +typeof (a >= 0) g; /* { dg-error "could not find an integer type of the same size as" "" { target ia32 } } */
2018-06-22 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-22 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-22 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-22 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-22 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-22 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) @@ -1078,6 +1078,9 @@ cp_build_reference_type (tree to_type, b { tree lvalue_ref, t; + if (to_type == error_mark_node) + return error_mark_node; + if (TREE_CODE (to_type) == REFERENCE_TYPE) { rval = rval && TYPE_REF_IS_RVALUE (to_type); --- 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-28 Jakub Jelinek <ja...@redhat.com> PR target/85095 * config/i386/i386.md (*add<mode>3_carry_0, *addsi3_carry_zext_0, *sub<mode>3_carry_0, *subsi3_carry_zext_0): New patterns. * gcc.target/i386/pr85095-1.c: New test. * gcc.target/i386/pr85095-2.c: New test. * gcc.c-torture/execute/pr85095.c: New test. --- gcc/config/i386/i386.md (revision 258930) +++ gcc/config/i386/i386.md (revision 258931) @@ -6685,6 +6685,20 @@ (define_insn "add<mode>3_carry" (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*add<mode>3_carry_0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (plus:SWI + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "0"))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)" + "adc{<imodesuffix>}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*addsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6701,6 +6715,20 @@ (define_insn "*addsi3_carry_zext" (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) +(define_insn "*addsi3_carry_zext_0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator" + [(reg FLAGS_REG) (const_int 0)]) + (match_operand:SI 1 "register_operand" "0")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "adc{l}\t{$0, %k0|%k0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "SI")]) + ;; There is no point to generate ADCX instruction. ADC is shorter and faster. (define_insn "addcarry<mode>" @@ -6741,6 +6769,20 @@ (define_insn "sub<mode>3_carry" (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*sub<mode>3_carry_0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)" + "sbb{<imodesuffix>}\t{$0, %0|%0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*subsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6756,6 +6798,21 @@ (define_insn "*subsi3_carry_zext" [(set_attr "type" "alu") (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") + (set_attr "mode" "SI")]) + +(define_insn "*subsi3_carry_zext_0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (minus:SI + (match_operand:SI 1 "register_operand" "0") + (match_operator:SI 2 "ix86_carry_flag_operator" + [(reg FLAGS_REG) (const_int 0)])))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "sbb{l}\t{$0, %k0|%k0, 0}" + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) (define_insn "subborrow<mode>" --- gcc/testsuite/gcc.target/i386/pr85095-1.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr85095-1.c (revision 258931) @@ -0,0 +1,33 @@ +/* PR target/85095 * +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ + +unsigned int +foo (unsigned int a, unsigned int b) +{ + a += b; + if (a < b) a++; + return a; +} + +#ifdef __x86_64__ +unsigned long long +bar (unsigned long long a, unsigned long long b) +{ + a += b; + if (a < b) a++; + return a; +} + +unsigned long long +baz (unsigned int a, unsigned int b) +{ + a += b; + if (a < b) a++; + return a; +} +#endif + +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "adcq\t\\\$0," 1 { target { ! ia32 } } } } */ --- gcc/testsuite/gcc.target/i386/pr85095-2.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr85095-2.c (revision 258931) @@ -0,0 +1,54 @@ +/* PR target/85095 * +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ + +unsigned int +f1 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +unsigned int +f2 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +#ifdef __x86_64__ +unsigned long long +f3 (unsigned long long a, unsigned long long b) +{ + unsigned long long i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +unsigned long long +f4 (unsigned long long a, unsigned long long b) +{ + unsigned long long i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +unsigned long long +f5 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +unsigned long long +f6 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a - i; +} +#endif + +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "sbbl\t\\\$0," 1 { target ia32 } } } */ +/* { dg-final { scan-assembler-times "adcl\t\\\$0," 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "sbbl\t\\\$0," 2 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "adcq\t\\\$0," 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-times "sbbq\t\\\$0," 1 { target { ! ia32 } } } } */ --- gcc/testsuite/gcc.c-torture/execute/pr85095.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr85095.c (revision 258931) @@ -0,0 +1,52 @@ +/* PR target/85095 */ + +__attribute__((noinline, noclone)) unsigned long +f1 (unsigned long a, unsigned long b) +{ + unsigned long i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +__attribute__((noinline, noclone)) unsigned long +f2 (unsigned long a, unsigned long b) +{ + unsigned long i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +__attribute__((noinline, noclone)) unsigned long +f3 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a + i; +} + +__attribute__((noinline, noclone)) unsigned long +f4 (unsigned int a, unsigned int b) +{ + unsigned int i = __builtin_add_overflow (a, b, &a); + return a - i; +} + +int +main () +{ + if (f1 (16UL, -18UL) != -2UL + || f1 (16UL, -17UL) != -1UL + || f1 (16UL, -16UL) != 1UL + || f1 (16UL, -15UL) != 2UL + || f2 (24UL, -26UL) != -2UL + || f2 (24UL, -25UL) != -1UL + || f2 (24UL, -24UL) != -1UL + || f2 (24UL, -23UL) != 0UL + || f3 (32U, -34U) != -2U + || f3 (32U, -33U) != -1U + || f3 (32U, -32U) != 1U + || f3 (32U, -31U) != 2U + || f4 (35U, -37U) != -2U + || f4 (35U, -36U) != -1U + || f4 (35U, -35U) != -1U + || f4 (35U, -34U) != 0U) + __builtin_abort (); + return 0; +}
2018-06-22 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-22 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-22 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-04 Jakub Jelinek <ja...@redhat.com> PR inline-asm/85172 * constexpr.c (cxx_eval_builtin_function_call): For calls to builtin_valid_in_constant_expr_p functions, don't call cxx_eval_constant_expression if argument is not potential_constant_expression. * g++.dg/ext/builtin13.C: New test. * g++.dg/ext/atomic-4.C: New test. --- gcc/cp/constexpr.c (revision 259103) +++ gcc/cp/constexpr.c (revision 259104) @@ -1189,8 +1189,14 @@ cxx_eval_builtin_function_call (const co bool dummy1 = false, dummy2 = false; for (i = 0; i < nargs; ++i) { - args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i), - false, &dummy1, &dummy2); + args[i] = CALL_EXPR_ARG (t, i); + /* If builtin_valid_in_constant_expr_p is true, + potential_constant_expression_1 has not recursed into the arguments + of the builtin, verify it here. */ + if (!builtin_valid_in_constant_expr_p (fun) + || potential_constant_expression (args[i])) + args[i] = cxx_eval_constant_expression (&new_ctx, args[i], false, + &dummy1, &dummy2); if (bi_const_p) /* For __built_in_constant_p, fold all expressions with constant values even if they aren't C++ constant-expressions. */ --- gcc/testsuite/g++.dg/ext/builtin13.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/builtin13.C (revision 259104) @@ -0,0 +1,9 @@ +// PR inline-asm/85172 +// { dg-do compile } +// { dg-options "" } + +int +foo () +{ + return !__builtin_constant_p (({ __asm (""); 0; })); +} --- gcc/testsuite/g++.dg/ext/atomic-4.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/atomic-4.C (revision 259104) @@ -0,0 +1,9 @@ +// PR inline-asm/85172 +// { dg-do compile } +// { dg-options "" } + +int +foo (int *p) +{ + return !__atomic_always_lock_free (4, ({ __asm (""); p; })); +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-05 Jakub Jelinek <ja...@redhat.com> PR c++/85208 * decl.c (start_decl): For DECL_DECOMPOSITION_P decls, don't call maybe_apply_pragma_weak here... (cp_maybe_mangle_decomp): ... but call it here instead. * g++.dg/cpp1z/decomp41.C: New test. --- gcc/cp/decl.c (revision 259154) +++ gcc/cp/decl.c (revision 259155) @@ -5090,7 +5090,7 @@ start_decl (const cp_declarator *declara } /* If #pragma weak was used, mark the decl weak now. */ - if (!processing_template_decl) + if (!processing_template_decl && !DECL_DECOMPOSITION_P (decl)) maybe_apply_pragma_weak (decl); if (TREE_CODE (decl) == FUNCTION_DECL @@ -7510,6 +7510,7 @@ cp_maybe_mangle_decomp (tree decl, tree for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) v[count - i - 1] = d; SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v)); + maybe_apply_pragma_weak (decl); } } --- gcc/testsuite/g++.dg/cpp1z/decomp41.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp41.C (revision 259155) @@ -0,0 +1,9 @@ +// PR c++/85208 +// { dg-do compile { target c++11 } } +// { dg-require-weak "" } +// { dg-options "" } + +#pragma weak _ZDC1d1e1fE +struct A { int i, j, k; }; +auto [a, b, c] = A (); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +auto [d, e, f] = A (); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-06 Jakub Jelinek <ja...@redhat.com> PR c++/85210 * pt.c (tsubst_decomp_names): Return error_mark_node and assert errorcount is set if tsubst doesn't return a VAR_DECL. * g++.dg/cpp1z/decomp42.C: New test. --- gcc/cp/pt.c (revision 259180) +++ gcc/cp/pt.c (revision 259181) @@ -16235,6 +16235,12 @@ tsubst_decomp_names (tree decl, tree pat DECL_HAS_VALUE_EXPR_P (decl2) = 1; if (VAR_P (decl3)) DECL_TEMPLATE_INSTANTIATED (decl3) = 1; + else + { + gcc_assert (errorcount); + decl = error_mark_node; + continue; + } maybe_push_decl (decl3); if (error_operand_p (decl3)) decl = error_mark_node; --- gcc/testsuite/g++.dg/cpp1z/decomp42.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp42.C (revision 259181) @@ -0,0 +1,18 @@ +// PR c++/85210 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { int i; }; + +template <int> +void +foo (int j) +{ + auto [j] = A{j}; // { dg-error "shadows a parameter" } +} // { dg-warning "decomposition declaration only available with" "" { target c++14_down } .-1 } + +void +bar () +{ + foo<0> (0); +}
2018-06-22 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-22 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) @@ -1981,8 +1981,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree if (TREE_CODE (rhs) == SSA_NAME) rhs = SSA_VAL (rhs); 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 @@ -1991,10 +1992,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-22 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-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-17 Jakub Jelinek <ja...@redhat.com> PR target/85430 * config/i386/i386.md (*ashlqi3_1_slp): Use alu1 type instead of alu. * gcc.dg/pr85430.c: New test. --- gcc/config/i386/i386.md (revision 259435) +++ gcc/config/i386/i386.md (revision 259436) @@ -10713,7 +10713,7 @@ (define_insn "*ashlqi3_1_slp" { switch (get_attr_type (insn)) { - case TYPE_ALU: + case TYPE_ALU1: gcc_assert (operands[1] == const1_rtx); return "add{b}\t%0, %0"; @@ -10729,12 +10729,12 @@ (define_insn "*ashlqi3_1_slp" (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") (match_operand 0 "register_operand")) (match_operand 1 "const1_operand")) - (const_string "alu") + (const_string "alu1") ] (const_string "ishift1"))) (set (attr "length_immediate") (if_then_else - (ior (eq_attr "type" "alu") + (ior (eq_attr "type" "alu1") (and (eq_attr "type" "ishift1") (and (match_operand 1 "const1_operand") (ior (match_test "TARGET_SHIFT1") --- gcc/testsuite/gcc.dg/pr85430.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr85430.c (revision 259436) @@ -0,0 +1,12 @@ +/* PR target/85430 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-ccp -fno-tree-fre" } */ + +typedef char V __attribute__((vector_size (4))); + +V +foo (V v) +{ + v[(V){}[0]] <<= 1; + return v; +}
2018-06-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-18 Jakub Jelinek <ja...@redhat.com> PR c++/84463 * typeck.c (cp_build_addr_expr_1): Move handling of offsetof-like tricks from here to ... * cp-gimplify.c (cp_fold) <case ADDR_EXPR>: ... here. Only use it if INDIRECT_REF's operand is INTEGER_CST cast to pointer type. * g++.dg/cpp0x/constexpr-nullptr-1.C: Add -O1 to dg-options. * g++.dg/cpp0x/constexpr-nullptr-2.C: Expect different diagnostics in two cases. Uncomment two other tests and add expected dg-error for them. * g++.dg/init/struct2.C: Cast to int rather than long to avoid -Wnarrowing diagnostics on some targets for c++11. * g++.dg/parse/array-size2.C: Remove xfail. * g++.dg/cpp0x/constexpr-84463.C: New test. --- gcc/cp/typeck.c (revision 259457) +++ gcc/cp/typeck.c (revision 259458) @@ -5893,19 +5893,6 @@ cp_build_addr_expr_1 (tree arg, bool str return arg; } - /* ??? Cope with user tricks that amount to offsetof. */ - if (TREE_CODE (argtype) != FUNCTION_TYPE - && TREE_CODE (argtype) != METHOD_TYPE - && argtype != unknown_type_node - && (val = get_base_address (arg)) - && COMPLETE_TYPE_P (TREE_TYPE (val)) - && INDIRECT_REF_P (val) - && TREE_CONSTANT (TREE_OPERAND (val, 0))) - { - tree type = build_pointer_type (argtype); - return fold_convert (type, fold_offsetof_1 (arg)); - } - /* Handle complex lvalues (when permitted) by reduction to simpler cases. */ val = unary_complex_lvalue (ADDR_EXPR, arg); --- gcc/cp/cp-gimplify.c (revision 259457) +++ gcc/cp/cp-gimplify.c (revision 259458) @@ -2215,6 +2215,28 @@ cp_fold (tree x) goto unary; case ADDR_EXPR: + loc = EXPR_LOCATION (x); + op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false); + + /* Cope with user tricks that amount to offsetof. */ + if (op0 != error_mark_node + && TREE_CODE (TREE_TYPE (op0)) != FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (op0)) != METHOD_TYPE) + { + tree val = get_base_address (op0); + if (val + && INDIRECT_REF_P (val) + && COMPLETE_TYPE_P (TREE_TYPE (val)) + && TREE_CONSTANT (TREE_OPERAND (val, 0))) + { + val = TREE_OPERAND (val, 0); + STRIP_NOPS (val); + if (TREE_CODE (val) == INTEGER_CST) + return fold_convert (TREE_TYPE (x), fold_offsetof_1 (op0)); + } + } + goto finish_unary; + case REALPART_EXPR: case IMAGPART_EXPR: rval_ops = false; @@ -2232,6 +2254,7 @@ cp_fold (tree x) loc = EXPR_LOCATION (x); op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops); + finish_unary: if (op0 != TREE_OPERAND (x, 0)) { if (op0 == error_mark_node) --- gcc/testsuite/g++.dg/parse/array-size2.C (revision 259457) +++ gcc/testsuite/g++.dg/parse/array-size2.C (revision 259458) @@ -15,6 +15,6 @@ void foo (void) { char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "constant" } - char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "constant" "" { xfail *-*-* } } + char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "constant" } bar (g, h); } --- gcc/testsuite/g++.dg/cpp0x/constexpr-84463.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/constexpr-84463.C (revision 259458) @@ -0,0 +1,22 @@ +// PR c++/84463 +// { dg-do compile { target c++11 } } + +struct S { int r; const unsigned char s[5]; }; +static constexpr S a[] = { { 0, "abcd" } }; +struct T { const unsigned char s[5]; }; +static constexpr T b[] = { { "abcd" } }; + +constexpr int +foo (const unsigned char *x) +{ + return x[0]; +} + +constexpr static const S *j = &a[0]; +constexpr static const int k = j->s[0]; +constexpr static int l = foo (a[0].s); +constexpr static int m = foo (j->s); +constexpr static const T *n = &b[0]; +constexpr static const int o = n->s[0]; +constexpr static int p = foo (b[0].s); +constexpr static int q = foo (n->s); --- gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-2.C (revision 259457) +++ gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-2.C (revision 259458) @@ -192,12 +192,11 @@ constexpr bool b11 = ps >= (S*)0; constexpr S* ps1 = ps; constexpr S* ps2 = ps1; -// The following aren't diagnosed due to a bug. -// constexpr int* pi0 = &((S*)0)->i; -// constexpr int* pi1 = &((S*)nullptr)->i; +constexpr int* pi0 = &((S*)0)->i; // { dg-error "null pointer|not a constant" } +constexpr int* pi1 = &((S*)nullptr)->i; // { dg-error "null pointer|not a constant" } -constexpr int* pj0 = &((S*)0)->j; // { dg-error "not a constant expression" } -constexpr int* pj1 = &((S*)nullptr)->j; // { dg-error "not a constant expression" } +constexpr int* pj0 = &((S*)0)->j; // { dg-error "null pointer|not a constant" } +constexpr int* pj1 = &((S*)nullptr)->j; // { dg-error "null pointer|not a constant" } constexpr int* psi = &ps->i; // { dg-error "null pointer|not a constant" } constexpr int* psj = &ps->j; // { dg-error "null pointer|not a constant" } --- gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-1.C (revision 259457) +++ gcc/testsuite/g++.dg/cpp0x/constexpr-nullptr-1.C (revision 259458) @@ -6,7 +6,7 @@ // c++/67376 on gcc-patches for additional background. // { dg-do compile { target c++11 } } -// { dg-options "-fdelete-null-pointer-checks -fdump-tree-optimized" } +// { dg-options "-O1 -fdelete-null-pointer-checks -fdump-tree-optimized" } // Runtime assert. Used for potentially invalid expressions. #define RA(e) ((e) ? (void)0 : __builtin_abort ()) --- gcc/testsuite/g++.dg/init/struct2.C (revision 259457) +++ gcc/testsuite/g++.dg/init/struct2.C (revision 259458) @@ -15,7 +15,7 @@ void saveOrLoad() { }; SaveLoadEntry trackEntries = { - ((long) (__SIZE_TYPE__) (&((Track *) 42)->soundName[0])) - 42, + ((int) (__SIZE_TYPE__) (&((Track *) 42)->soundName[0])) - 42, 0, 1 }; saveLoadEntries(&trackEntries);
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-18 David Malcolm <dmalc...@redhat.com> PR jit/85384 * acx.m4 (GCC_BASE_VER): Remove \$\$ from sed expression. * configure.ac (gcc-driver-name.h): Honor --with-gcc-major-version by using gcc_base_ver to generate a gcc_driver_version, and use it when generating GCC_DRIVER_NAME. * configure: Regenerate. * configure: Regenerate. --- config/acx.m4 (revision 259461) +++ config/acx.m4 (revision 259462) @@ -246,7 +246,7 @@ AC_DEFUN([GCC_BASE_VER], [AS_HELP_STRING([--with-gcc-major-version-only], [use only GCC major number in filesystem paths])], [if test x$with_gcc_major_version_only = xyes ; then changequote(,)dnl - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" changequote([,])dnl fi ]) --- gcc/configure.ac (revision 259461) +++ gcc/configure.ac (revision 259462) @@ -6499,8 +6499,10 @@ AC_DEFINE_UNQUOTED(DIAGNOSTICS_COLOR_DEF # Generate gcc-driver-name.h containing GCC_DRIVER_NAME for the benefit # of jit/jit-playback.c. +gcc_driver_version=`eval "${get_gcc_base_ver} $srcdir/BASE-VER"` +echo "gcc_driver_version: ${gcc_driver_version}" cat > gcc-driver-name.h <<EOF -#define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}" +#define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_driver_version}${exeext}" EOF # Check whether --enable-default-pie was given. --- liboffloadmic/plugin/configure.jj 2017-04-20 12:16:31.814177527 +0200 +++ liboffloadmic/plugin/configure 2018-06-22 14:24:50.983906449 +0200 @@ -14187,7 +14187,7 @@ hardcode_into_libs=no # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- liboffloadmic/configure.jj 2017-04-20 12:16:24.561275265 +0200 +++ liboffloadmic/configure 2018-06-22 14:24:32.335906853 +0200 @@ -14492,7 +14492,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- fixincludes/configure.jj 2017-04-20 12:20:04.429312370 +0200 +++ fixincludes/configure 2018-06-22 14:22:37.236909347 +0200 @@ -5401,7 +5401,7 @@ _ACEOF # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libhsail-rt/configure.jj 2017-04-20 12:20:03.756321439 +0200 +++ libhsail-rt/configure 2018-06-22 14:24:05.829907427 +0200 @@ -14414,7 +14414,7 @@ _ACEOF # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libquadmath/configure.jj 2017-04-20 12:16:38.677085044 +0200 +++ libquadmath/configure 2018-06-22 14:25:00.680906239 +0200 @@ -12929,7 +12929,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libgcc/configure.jj 2017-12-06 11:01:52.053549040 +0100 +++ libgcc/configure 2018-06-22 14:23:51.398907740 +0200 @@ -5298,7 +5298,7 @@ esac # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libobjc/configure.jj 2017-04-20 12:20:03.002331600 +0200 +++ libobjc/configure 2018-06-22 14:24:26.556906978 +0200 @@ -11708,7 +11708,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libgomp/configure.jj 2017-04-20 12:16:21.015323050 +0200 +++ libgomp/configure 2018-06-22 14:24:00.982907532 +0200 @@ -16823,7 +16823,7 @@ CFLAGS="$save_CFLAGS" # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libmpx/configure.jj 2017-04-20 12:16:33.449155494 +0200 +++ libmpx/configure 2018-06-22 14:24:19.915907122 +0200 @@ -11596,7 +11596,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libstdc++-v3/configure.jj 2018-05-26 08:46:17.261127872 +0200 +++ libstdc++-v3/configure 2018-06-22 14:25:22.732905761 +0200 @@ -81697,7 +81697,7 @@ $as_echo "$gxx_include_dir" >&6; } # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libvtv/configure.jj 2017-04-20 12:20:03.113330104 +0200 +++ libvtv/configure 2018-06-22 14:25:32.336905553 +0200 @@ -15516,7 +15516,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libcilkrts/configure.jj 2017-04-20 12:20:04.218315213 +0200 +++ libcilkrts/configure 2018-06-22 14:23:37.445908042 +0200 @@ -15413,7 +15413,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libssp/configure.jj 2017-04-20 12:20:04.189315604 +0200 +++ libssp/configure 2018-06-22 14:25:13.745905956 +0200 @@ -11082,7 +11082,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libcc1/configure.jj 2017-04-20 12:16:42.528033149 +0200 +++ libcc1/configure 2018-06-22 14:23:30.710908188 +0200 @@ -14315,7 +14315,7 @@ _ACEOF # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libatomic/configure.jj 2017-04-20 12:18:57.940208363 +0200 +++ libatomic/configure 2018-06-22 14:23:26.273908284 +0200 @@ -12333,6 +12333,7 @@ _ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 2" >&5 $as_echo_n "checking for __atomic_load/store for size 2... " >&6; } if test "${libat_cv_have_at_ldst_2+set}" = set; then : @@ -12400,6 +12401,7 @@ _ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 4" >&5 $as_echo_n "checking for __atomic_load/store for size 4... " >&6; } if test "${libat_cv_have_at_ldst_4+set}" = set; then : @@ -12467,6 +12469,7 @@ _ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 8" >&5 $as_echo_n "checking for __atomic_load/store for size 8... " >&6; } if test "${libat_cv_have_at_ldst_8+set}" = set; then : @@ -12534,6 +12537,7 @@ _ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load/store for size 16" >&5 $as_echo_n "checking for __atomic_load/store for size 16... " >&6; } if test "${libat_cv_have_at_ldst_16+set}" = set; then : @@ -12602,6 +12606,7 @@ _ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_test_and_set for size 1" >&5 $as_echo_n "checking for __atomic_test_and_set for size 1... " >&6; } if test "${libat_cv_have_at_tas_1+set}" = set; then : @@ -15267,7 +15272,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- gcc/configure.jj 2018-03-02 17:53:27.095709209 +0100 +++ gcc/configure 2018-06-22 14:22:46.850909138 +0200 @@ -11871,7 +11871,7 @@ EOF # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi @@ -25225,6 +25225,7 @@ $as_echo "#define HAVE_AS_SPARC5_VIS4 1" fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for SPARC6 instructions" >&5 $as_echo_n "checking assembler for SPARC6 instructions... " >&6; } if test "${gcc_cv_as_sparc_sparc6+set}" = set; then : @@ -25261,6 +25262,7 @@ $as_echo "#define HAVE_AS_SPARC6 1" >>co fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for LEON instructions" >&5 $as_echo_n "checking assembler for LEON instructions... " >&6; } if test "${gcc_cv_as_sparc_leon+set}" = set; then : @@ -29785,8 +29787,10 @@ _ACEOF # Generate gcc-driver-name.h containing GCC_DRIVER_NAME for the benefit # of jit/jit-playback.c. +gcc_driver_version=`eval "${get_gcc_base_ver} $srcdir/BASE-VER"` +echo "gcc_driver_version: ${gcc_driver_version}" cat > gcc-driver-name.h <<EOF -#define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}" +#define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_driver_version}${exeext}" EOF # Check whether --enable-default-pie was given. --- configure.jj 2017-04-20 12:18:58.159205412 +0200 +++ configure 2018-06-22 14:22:19.003909742 +0200 @@ -6620,7 +6620,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libitm/configure.jj 2017-04-20 12:16:13.068430141 +0200 +++ libitm/configure 2018-06-22 14:24:10.716907321 +0200 @@ -17647,7 +17647,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libgfortran/configure.jj 2017-04-20 12:20:03.241328379 +0200 +++ libgfortran/configure 2018-06-22 14:23:56.690907625 +0200 @@ -26370,7 +26370,7 @@ rm -f core conftest.err conftest.$ac_obj # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libada/configure.jj 2017-06-21 21:03:08.490899652 +0200 +++ libada/configure 2018-06-22 14:23:21.519908387 +0200 @@ -3018,7 +3018,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libsanitizer/configure.jj 2017-04-20 12:16:48.744949371 +0200 +++ libsanitizer/configure 2018-06-22 14:25:07.905906082 +0200 @@ -16511,7 +16511,7 @@ fi # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi --- libffi/configure.jj 2017-04-20 12:20:03.977318461 +0200 +++ libffi/configure 2018-06-22 14:23:44.290907894 +0200 @@ -16444,7 +16444,7 @@ $as_echo "$as_me: versioning on shared l # Check whether --with-gcc-major-version-only was given. if test "${with_gcc_major_version_only+set}" = set; then : withval=$with_gcc_major_version_only; if test x$with_gcc_major_version_only = xyes ; then - get_gcc_base_ver="sed -e 's/^\([0-9]*\).*\$\$/\1/'" + get_gcc_base_ver="sed -e 's/^\([0-9]*\).*/\1/'" fi fi
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-19 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/85446 * match.pd ((intptr_t) x eq/ne CST to x eq/ne (typeof x) cst): Require the integral and pointer types to have the same precision. --- gcc/match.pd (revision 259487) +++ gcc/match.pd (revision 259488) @@ -3711,10 +3711,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for cmp (ne eq) (simplify (cmp (convert @0) INTEGER_CST@1) - (if ((POINTER_TYPE_P (TREE_TYPE (@0)) && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@0))) - && INTEGRAL_TYPE_P (TREE_TYPE (@1))) - || (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && POINTER_TYPE_P (TREE_TYPE (@1)) - && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@1))))) + (if (((POINTER_TYPE_P (TREE_TYPE (@0)) + && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@0))) + && INTEGRAL_TYPE_P (TREE_TYPE (@1))) + || (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && POINTER_TYPE_P (TREE_TYPE (@1)) + && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@1))))) + && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))) (cmp @0 (convert @1))))) /* Non-equality compare simplifications from fold_binary */
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-04-27 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/85529 * tree-ssa-reassoc.c (optimize_range_tests_var_bound): Add FIRST_BB argument. Don't call get_nonzero_bits if opcode is ERROR_MARK_NODE, rhs2 def stmt's bb is dominated by first_bb and it isn't an obvious zero extension or masking of the MSB bit. (optimize_range_tests): Add FIRST_BB argument, pass it through to optimize_range_tests_var_bound. (maybe_optimize_range_tests, reassociate_bb): Adjust optimize_range_tests callers. * gcc.c-torture/execute/pr85529-1.c: New test. * gcc.c-torture/execute/pr85529-2.c: New test. * gcc.dg/pr85529.c: New test. --- gcc/tree-ssa-reassoc.c (revision 259696) +++ gcc/tree-ssa-reassoc.c (revision 259697) @@ -2878,7 +2878,8 @@ optimize_range_tests_to_bit_test (enum t static bool optimize_range_tests_var_bound (enum tree_code opcode, int first, int length, vec<operand_entry *> *ops, - struct range_entry *ranges) + struct range_entry *ranges, + basic_block first_bb) { int i; bool any_changes = false; @@ -2975,6 +2976,60 @@ optimize_range_tests_var_bound (enum tre if (idx == NULL) continue; + /* maybe_optimize_range_tests allows statements without side-effects + in the basic blocks as long as they are consumed in the same bb. + Make sure rhs2's def stmt is not among them, otherwise we can't + use safely get_nonzero_bits on it. E.g. in: + # RANGE [-83, 1] NONZERO 173 + # k_32 = PHI <k_47(13), k_12(9)> + ... + if (k_32 >= 0) + goto <bb 5>; [26.46%] + else + goto <bb 9>; [73.54%] + + <bb 5> [local count: 140323371]: + # RANGE [0, 1] NONZERO 1 + _5 = (int) k_32; + # RANGE [0, 4] NONZERO 4 + _21 = _5 << 2; + # RANGE [0, 4] NONZERO 4 + iftmp.0_44 = (char) _21; + if (k_32 < iftmp.0_44) + goto <bb 6>; [84.48%] + else + goto <bb 9>; [15.52%] + the ranges on _5/_21/iftmp.0_44 are flow sensitive, assume that + k_32 >= 0. If we'd optimize k_32 >= 0 to true and k_32 < iftmp.0_44 + to (unsigned) k_32 < (unsigned) iftmp.0_44, then we would execute + those stmts even for negative k_32 and the value ranges would be no + longer guaranteed and so the optimization would be invalid. */ + if (opcode == ERROR_MARK) + { + gimple *g = SSA_NAME_DEF_STMT (rhs2); + basic_block bb2 = gimple_bb (g); + if (bb2 + && bb2 != first_bb + && dominated_by_p (CDI_DOMINATORS, bb2, first_bb)) + { + /* As an exception, handle a few common cases. */ + if (gimple_assign_cast_p (g) + && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g))) + && TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g))) + && (TYPE_PRECISION (TREE_TYPE (rhs2)) + > TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (g))))) + /* Zero-extension is always ok. */ ; + else if (is_gimple_assign (g) + && gimple_assign_rhs_code (g) == BIT_AND_EXPR + && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST + && !wi::neg_p (gimple_assign_rhs2 (g))) + /* Masking with INTEGER_CST with MSB clear is always ok + too. */ ; + else + continue; + } + } + wide_int nz = get_nonzero_bits (rhs2); if (wi::neg_p (nz)) continue; @@ -3101,11 +3156,12 @@ optimize_range_tests_var_bound (enum tre maybe_optimize_range_tests for inter-bb range optimization. In that case if oe->op is NULL, oe->id is bb->index whose GIMPLE_COND is && or ||ed into the test, and oe->rank says - the actual opcode. */ + the actual opcode. + FIRST_BB is the first basic block if OPCODE is ERROR_MARK. */ static bool optimize_range_tests (enum tree_code opcode, - vec<operand_entry *> *ops) + vec<operand_entry *> *ops, basic_block first_bb) { unsigned int length = ops->length (), i, j, first; operand_entry *oe; @@ -3183,7 +3239,7 @@ optimize_range_tests (enum tree_code opc any_changes |= optimize_range_tests_to_bit_test (opcode, first, length, ops, ranges); any_changes |= optimize_range_tests_var_bound (opcode, first, length, ops, - ranges); + ranges, first_bb); if (any_changes && opcode != ERROR_MARK) { @@ -3930,7 +3986,7 @@ maybe_optimize_range_tests (gimple *stmt break; } if (ops.length () > 1) - any_changes = optimize_range_tests (ERROR_MARK, &ops); + any_changes = optimize_range_tests (ERROR_MARK, &ops, first_bb); if (any_changes) { unsigned int idx, max_idx = 0; @@ -5682,7 +5738,7 @@ reassociate_bb (basic_block bb) if (is_vector) optimize_vec_cond_expr (rhs_code, &ops); else - optimize_range_tests (rhs_code, &ops); + optimize_range_tests (rhs_code, &ops, NULL); } if (rhs_code == MULT_EXPR && !is_vector) --- gcc/testsuite/gcc.c-torture/execute/pr85529-1.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr85529-1.c (revision 259697) @@ -0,0 +1,28 @@ +/* PR tree-optimization/85529 */ + +struct S { int a; }; + +int b, c = 1, d, e, f; +static int g; +volatile struct S s; + +signed char +foo (signed char i, int j) +{ + return i < 0 ? i : i << j; +} + +int +main () +{ + signed char k = -83; + if (!d) + goto L; + k = e || f; +L: + for (; b < 1; b++) + s.a != (k < foo (k, 2) && (c = k = g)); + if (c != 1) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.c-torture/execute/pr85529-2.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr85529-2.c (revision 259697) @@ -0,0 +1,25 @@ +/* PR tree-optimization/85529 */ + +__attribute__((noinline, noclone)) int +foo (int x) +{ + x &= 63; + x -= 50; + x |= 1; + if (x < 0) + return 1; + int y = x >> 2; + if (x >= y) + return 1; + return 0; +} + +int +main () +{ + int i; + for (i = 0; i < 63; i++) + if (foo (i) != 1) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.dg/pr85529.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr85529.c (revision 259697) @@ -0,0 +1,27 @@ +/* PR tree-optimization/85529 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-ssa-phiopt" } */ + +__attribute__((noinline, noclone)) int +foo (int x) +{ + x &= 31; + x -= 25; + x *= 2; + if (x < 0) + return 1; + int y = x >> 2; + if (x >= y) + return 1; + return 0; +} + +int +main () +{ + int i; + for (i = 0; i < 63; i++) + if (foo (i) != 1) + __builtin_abort (); + return 0; +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-05-01 Jakub Jelinek <ja...@redhat.com> PR web/85578 * doc/install.texi2html: Replace _002d with - and _002a with * in generated html files using sed. --- gcc/doc/install.texi2html (revision 259800) +++ gcc/doc/install.texi2html (revision 259801) @@ -52,7 +52,10 @@ for x in index.html specific.html prereq do define=`echo $x | sed -e 's/\.//g'` echo "define = $define" - $MAKEINFO --no-number-sections -I $SOURCEDIR -I $SOURCEDIR/include -I $DESTDIR $SOURCEDIR/install.texi --html --no-split -D$define -o$DESTDIR/$x + $MAKEINFO --no-number-sections -I $SOURCEDIR -I $SOURCEDIR/include -I $DESTDIR $SOURCEDIR/install.texi --html --no-split -D$define -o$DESTDIR/temp.html + # Use sed to work around makeinfo 4.7 brokenness. + sed -e 's/_002d/-/g' -e 's/_002a/*/g' $DESTDIR/temp.html > $DESTDIR/$x + rm $DESTDIR/temp.html done rm $DESTDIR/gcc-vers.texi
2018-06-22 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-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-06-22 Jakub Jelinek <ja...@redhat.com> PR c++/85662 * g++.dg/ext/offsetof3.C: New test. 2018-05-10 Jakub Jelinek <ja...@redhat.com> PR c++/85662 * c-common.h (fold_offsetof_1): Removed. (fold_offsetof): Add TYPE argument defaulted to size_type_node and CTX argument defaulted to ERROR_MARK. * c-common.c (fold_offsetof_1): Renamed to ... (fold_offsetof): ... this. Remove wrapper function. Add TYPE argument, convert the pointer constant to TYPE and use size_binop with PLUS_EXPR instead of fold_build_pointer_plus if type is not a pointer type. Adjust recursive calls. * c-fold.c (c_fully_fold_internal): Use fold_offsetof rather than fold_offsetof_1, pass TREE_TYPE (expr) as TYPE to it and drop the fold_convert_loc. * c-typeck.c (build_unary_op): Use fold_offsetof rather than fold_offsetof_1, pass argtype as TYPE to it and drop the fold_convert_loc. * cp-gimplify.c (cp_fold): Use fold_offsetof rather than fold_offsetof_1, pass TREE_TYPE (x) as TYPE to it and drop the fold_convert. * g++.dg/ext/offsetof2.C: New test. --- gcc/c-family/c-common.c (revision 260915) +++ gcc/c-family/c-common.c (revision 260916) @@ -6251,10 +6251,11 @@ c_common_to_target_charset (HOST_WIDE_IN /* Fold an offsetof-like expression. EXPR is a nested sequence of component references with an INDIRECT_REF of a constant at the bottom; much like the - traditional rendering of offsetof as a macro. Return the folded result. */ + traditional rendering of offsetof as a macro. TYPE is the desired type of + the whole expression. Return the folded result. */ tree -fold_offsetof_1 (tree expr, enum tree_code ctx) +fold_offsetof (tree expr, tree type, enum tree_code ctx) { tree base, off, t; tree_code code = TREE_CODE (expr); @@ -6279,10 +6280,10 @@ fold_offsetof_1 (tree expr, enum tree_co error ("cannot apply %<offsetof%> to a non constant address"); return error_mark_node; } - return TREE_OPERAND (expr, 0); + return convert (type, TREE_OPERAND (expr, 0)); case COMPONENT_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); if (base == error_mark_node) return base; @@ -6299,7 +6300,7 @@ fold_offsetof_1 (tree expr, enum tree_co break; case ARRAY_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); if (base == error_mark_node) return base; @@ -6356,23 +6357,16 @@ fold_offsetof_1 (tree expr, enum tree_co /* Handle static members of volatile structs. */ t = TREE_OPERAND (expr, 1); gcc_assert (VAR_P (t)); - return fold_offsetof_1 (t); + return fold_offsetof (t, type); default: gcc_unreachable (); } + if (!POINTER_TYPE_P (type)) + return size_binop (PLUS_EXPR, base, convert (type, off)); return fold_build_pointer_plus (base, off); } - -/* Likewise, but convert it to the return type of offsetof. */ - -tree -fold_offsetof (tree expr) -{ - return convert (size_type_node, fold_offsetof_1 (expr)); -} - /* *PTYPE is an incomplete array. Complete it with a domain based on INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT --- gcc/c-family/c-common.h (revision 260915) +++ gcc/c-family/c-common.h (revision 260916) @@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree); extern void verify_sequence_points (tree); -extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); -extern tree fold_offsetof (tree); +extern tree fold_offsetof (tree, tree = size_type_node, + tree_code ctx = ERROR_MARK); extern int complete_array_type (tree *, tree, bool); --- gcc/c/c-fold.c (revision 260915) +++ gcc/c/c-fold.c (revision 260916) @@ -473,7 +473,7 @@ c_fully_fold_internal (tree expr, bool i && (op1 = get_base_address (op0)) != NULL_TREE && INDIRECT_REF_P (op1) && TREE_CONSTANT (TREE_OPERAND (op1, 0))) - ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); + ret = fold_offsetof (op0, TREE_TYPE (expr)); else if (op0 != orig_op0 || in_init) ret = in_init ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) --- gcc/c/c-typeck.c (revision 260915) +++ gcc/c/c-typeck.c (revision 260916) @@ -4676,7 +4676,7 @@ build_unary_op (location_t location, enu if (val && INDIRECT_REF_P (val) && TREE_CONSTANT (TREE_OPERAND (val, 0))) { - ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg)); + ret = fold_offsetof (arg, argtype); goto return_build_unary_op; } --- gcc/cp/cp-gimplify.c (revision 260915) +++ gcc/cp/cp-gimplify.c (revision 260916) @@ -2233,7 +2233,7 @@ cp_fold (tree x) val = TREE_OPERAND (val, 0); STRIP_NOPS (val); if (TREE_CODE (val) == INTEGER_CST) - return fold_convert (TREE_TYPE (x), fold_offsetof_1 (op0)); + return fold_offsetof (op0, TREE_TYPE (x)); } } goto finish_unary; --- gcc/testsuite/g++.dg/ext/offsetof2.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/offsetof2.C (revision 260916) @@ -0,0 +1,6 @@ +// PR c++/85662 +// { dg-do compile { target c++11 } } + +struct S { unsigned long x[31]; }; +struct T { bool b; S f; }; +static_assert (__builtin_offsetof (T, f.x[31 - 1]) == __builtin_offsetof (T, f.x[30]), ""); --- gcc/testsuite/g++.dg/ext/offsetof3.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/offsetof3.C (revision 261910) @@ -0,0 +1,5 @@ +// PR c++/85662 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +#include "offsetof2.C"
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-05-11 Jakub Jelinek <ja...@redhat.com> PR c/85696 * c-omp.c (c_omp_predetermined_sharing): Return OMP_CLAUSE_DEFAULT_SHARED for artificial vars with integral type. * c-typeck.c (c_finish_omp_clauses): Don't use c_omp_predetermined_sharing, instead just check TREE_READONLY. * cp-tree.h (cxx_omp_predetermined_sharing_1): New prototype. * cp-gimplify.c (cxx_omp_predetermined_sharing): New wrapper around cxx_omp_predetermined_sharing_1. Rename old function to ... (cxx_omp_predetermined_sharing_1): ... this. * semantics.c (finish_omp_clauses): Use cxx_omp_predetermined_sharing_1 instead of cxx_omp_predetermined_sharing. * c-c++-common/gomp/pr85696.c: New test. --- gcc/c-family/c-omp.c (revision 260916) +++ gcc/c-family/c-omp.c (revision 260917) @@ -1611,5 +1611,13 @@ c_omp_predetermined_sharing (tree decl) if (TREE_READONLY (decl)) return OMP_CLAUSE_DEFAULT_SHARED; + /* Predetermine artificial variables holding integral values, those + are usually result of gimplify_one_sizepos or SAVE_EXPR + gimplification. */ + if (VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && INTEGRAL_TYPE_P (TREE_TYPE (decl))) + return OMP_CLAUSE_DEFAULT_SHARED; + return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } --- gcc/c/c-typeck.c.jj 2018-06-22 19:47:39.834968620 +0200 +++ gcc/c/c-typeck.c 2018-06-22 22:10:04.994885151 +0200 @@ -13760,22 +13760,11 @@ c_finish_omp_clauses (tree clauses, enum if (VAR_P (t) && DECL_THREAD_LOCAL_P (t)) share_name = "threadprivate"; - else switch (c_omp_predetermined_sharing (t)) + else if (TREE_READONLY (t)) { - case OMP_CLAUSE_DEFAULT_UNSPECIFIED: - break; - case OMP_CLAUSE_DEFAULT_SHARED: /* const vars may be specified in firstprivate clause. */ - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE - && TREE_READONLY (t)) - break; - share_name = "shared"; - break; - case OMP_CLAUSE_DEFAULT_PRIVATE: - share_name = "private"; - break; - default: - gcc_unreachable (); + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE) + share_name = "shared"; } if (share_name) { --- gcc/cp/cp-gimplify.c (revision 260916) +++ gcc/cp/cp-gimplify.c (revision 260917) @@ -1958,7 +1958,7 @@ cxx_omp_const_qual_no_mutable (tree decl /* True if OpenMP sharing attribute of DECL is predetermined. */ enum omp_clause_default_kind -cxx_omp_predetermined_sharing (tree decl) +cxx_omp_predetermined_sharing_1 (tree decl) { /* Static data members are predetermined shared. */ if (TREE_STATIC (decl)) @@ -1974,6 +1974,32 @@ cxx_omp_predetermined_sharing (tree decl return OMP_CLAUSE_DEFAULT_SHARED; return OMP_CLAUSE_DEFAULT_UNSPECIFIED; +} + +/* Likewise, but also include the artificial vars. We don't want to + disallow the artificial vars being mentioned in explicit clauses, + as we use artificial vars e.g. for loop constructs with random + access iterators other than pointers, but during gimplification + we want to treat them as predetermined. */ + +enum omp_clause_default_kind +cxx_omp_predetermined_sharing (tree decl) +{ + enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl); + if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED) + return ret; + + /* Predetermine artificial variables holding integral values, those + are usually result of gimplify_one_sizepos or SAVE_EXPR + gimplification. */ + if (VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && INTEGRAL_TYPE_P (TREE_TYPE (decl)) + && !(DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl))) + return OMP_CLAUSE_DEFAULT_SHARED; + + return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } /* Finalize an implicitly determined clause. */ --- gcc/cp/semantics.c (revision 260916) +++ gcc/cp/semantics.c (revision 260917) @@ -7311,7 +7311,7 @@ finish_omp_clauses (tree clauses, enum c if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) share_name = "threadprivate"; - else switch (cxx_omp_predetermined_sharing (t)) + else switch (cxx_omp_predetermined_sharing_1 (t)) { case OMP_CLAUSE_DEFAULT_UNSPECIFIED: break; --- gcc/cp/cp-tree.h (revision 260916) +++ gcc/cp/cp-tree.h (revision 260917) @@ -7410,6 +7410,7 @@ extern int cp_gimplify_expr (tree *, g gimple_seq *); extern void cp_genericize (tree); extern bool cxx_omp_const_qual_no_mutable (tree); +extern enum omp_clause_default_kind cxx_omp_predetermined_sharing_1 (tree); extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree); extern tree cxx_omp_clause_default_ctor (tree, tree, tree); extern tree cxx_omp_clause_copy_ctor (tree, tree, tree); --- gcc/testsuite/c-c++-common/gomp/pr85696.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr85696.c (revision 260917) @@ -0,0 +1,20 @@ +/* PR c/85696 */ + +#ifndef __cplusplus +void +foo (int n, int a[][n]) +{ + #pragma omp parallel shared(a) default(none) + #pragma omp master + a[23][0] = 42; +} +#endif + +void +bar (int n, void *p) +{ + int (*a)[n] = (int (*)[n]) p; + #pragma omp parallel shared(a) default(none) + #pragma omp master + a[23][0] = 42; +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-05-29 Jakub Jelinek <ja...@redhat.com> PR c++/85952 * init.c (build_aggr_init): For structured binding initialized from array call mark_rvalue_use on the initializer. * g++.dg/warn/Wunused-var-33.C: New test. --- gcc/cp/init.c (revision 260918) +++ gcc/cp/init.c (revision 260919) @@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp)) { from_array = 1; + init = mark_rvalue_use (init); if (init && DECL_P (init) && !(flags & LOOKUP_ONLYCONVERTING)) { --- gcc/testsuite/g++.dg/warn/Wunused-var-33.C (nonexistent) +++ gcc/testsuite/g++.dg/warn/Wunused-var-33.C (revision 260919) @@ -0,0 +1,37 @@ +// PR c++/85952 +// { dg-do compile { target c++11 } } +// { dg-options "-Wunused-but-set-variable" } + +int +foo () +{ + int a[2] = {1, 2}; // { dg-bogus "set but not used" } */ + auto [x, y] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + return x + y; +} + +struct S { int d, e; }; + +int +bar () +{ + S a = {1, 2}; + auto [x, y] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + return x + y; +} + +int +baz () +{ + S a = {1, 2}; + auto & [x, y] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + return x + y; +} + +int +qux () +{ + int a[2] = {1, 2}; + auto & [x, y] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + return x + y; +}
2018-06-22 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-06-04 Jakub Jelinek <ja...@redhat.com> PR c++/86025 * tree.c (inchash::add_expr): Handle IDENTIFIER_NODE. * c-c++-common/gomp/pr86025.c: New test. --- gcc/tree.c (revision 261137) +++ gcc/tree.c (revision 261138) @@ -7351,6 +7351,9 @@ add_expr (const_tree t, inchash::hash &h for (i = 0; i < TREE_VEC_LENGTH (t); ++i) inchash::add_expr (TREE_VEC_ELT (t, i), hstate, flags); return; + case IDENTIFIER_NODE: + hstate.add_object (IDENTIFIER_HASH_VALUE (t)); + return; case FUNCTION_DECL: /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form. Otherwise nodes that compare equal according to operand_equal_p might --- gcc/testsuite/c-c++-common/gomp/pr86025.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr86025.c (revision 261138) @@ -0,0 +1,20 @@ +/* PR c++/86025 */ +/* { dg-do compile } */ +/* { dg-additional-options "-Wduplicated-branches" } */ + +int i; + +void +foo (int x) +{ + if (x) + { + #pragma omp critical (foo) + i++; + } + else + { + #pragma omp critical + i++; + } +}
2018-06-22 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-22 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-22 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-22 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) @@ -5403,10 +5403,8 @@ check_nonnull_arg (void *ctx, tree param if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE) return; - /* When not optimizing diagnose the simple cases of null arguments. - When optimization is enabled defer the checking until expansion - when more cases can be detected. */ - if (integer_zerop (param)) + /* Diagnose the simple cases of null arguments. */ + if (integer_zerop (fold_for_warn (param))) { warning_at (pctx->loc, 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; +}