Hi! I've backported these 42 commits (one is actually combined from two) from trunk to 7.x branch, bootstrapped/regtested on x86_64-linux and i686-linux and committed.
Jakub
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-05 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/83605 * gimple-ssa-strength-reduction.c: Include tree-eh.h. (find_candidates_dom_walker::before_dom_children): Ignore stmts that can throw. * gcc.dg/pr83605.c: New test. --- gcc/gimple-ssa-strength-reduction.c (revision 256273) +++ gcc/gimple-ssa-strength-reduction.c (revision 256274) @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. #include "params.h" #include "tree-ssa-address.h" #include "tree-affine.h" +#include "tree-eh.h" #include "builtins.h" /* Information about a strength reduction candidate. Each statement @@ -1747,6 +1748,9 @@ find_candidates_dom_walker::before_dom_c { gimple *gs = gsi_stmt (gsi); + if (stmt_could_throw_p (gs)) + continue; + if (gimple_vuse (gs) && gimple_assign_single_p (gs)) slsr_process_ref (gs); --- gcc/testsuite/gcc.dg/pr83605.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83605.c (revision 256274) @@ -0,0 +1,20 @@ +/* PR tree-optimization/83605 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftrapv -fexceptions -fnon-call-exceptions" } */ + +int a; + +int +foo (int x) +{ + int b = a; + { + int c; + int *d = (x == 0) ? &c : &b; + + for (a = 0; a < 2; ++a) + c = (x + b) < a; + + return *d; + } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-09 Jakub Jelinek <ja...@redhat.com> PR preprocessor/83722 * gcc.c (try_generate_repro): Pass &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1] rather than &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1] as last argument to do_report_bug. --- gcc/gcc.c (revision 256366) +++ gcc/gcc.c (revision 256367) @@ -7035,8 +7035,8 @@ try_generate_repro (const char **argv) /* In final attempt we append compiler options and preprocesssed code to last generated .out file with configuration and backtrace. */ - char **output = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1]; - do_report_bug (new_argv, nargs, stderr_commented, output); + char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1]; + do_report_bug (new_argv, nargs, stderr_commented, err); } out:
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-16 Jakub Jelinek <ja...@redhat.com> PR c++/83817 * pt.c (tsubst_copy_and_build) <case CALL_EXPR>: If function is AGGR_INIT_EXPR rather than CALL_EXPR, set AGGR_INIT_FROM_THUNK_P instead of CALL_FROM_THUNK_P. * g++.dg/cpp1y/pr83817.C: New test. --- gcc/cp/pt.c (revision 256725) +++ gcc/cp/pt.c (revision 256726) @@ -17819,7 +17819,10 @@ tsubst_copy_and_build (tree t, CALL_EXPR_REVERSE_ARGS (function) = rev; if (thk) { - CALL_FROM_THUNK_P (function) = true; + if (TREE_CODE (function) == CALL_EXPR) + CALL_FROM_THUNK_P (function) = true; + else + AGGR_INIT_FROM_THUNK_P (function) = true; /* The thunk location is not interesting. */ SET_EXPR_LOCATION (function, UNKNOWN_LOCATION); } --- gcc/testsuite/g++.dg/cpp1y/pr83817.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1y/pr83817.C (revision 256726) @@ -0,0 +1,17 @@ +// PR c++/83817 +// { dg-do compile { target c++14 } } + +struct A; +struct B { template <typename> using C = A; }; +struct D : B { struct F { typedef C<char> E; }; }; +struct G { + struct I { I (D, A &); } h; + D::F::E &k (); + D j; + G (G &&) : h (j, k ()) {} +}; +struct N { G l; }; +typedef N (*M)(N &); +struct H { const char *o; M s; }; +N foo (N &); +H r { "", [](auto &x) { return foo (x); }};
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-18 Jakub Jelinek <ja...@redhat.com> PR c++/83824 * parser.c (attr_chainon): New function. (cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq, cp_parser_namespace_definition, cp_parser_init_declarator, cp_parser_type_specifier_seq, cp_parser_parameter_declaration, cp_parser_gnu_attributes_opt): Use it. (cp_parser_member_declaration, cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration): Likewise. Don't reset prefix_attributes if attributes is error_mark_node. * g++.dg/cpp0x/pr83824.C: New test. --- gcc/cp/parser.c (revision 256822) +++ gcc/cp/parser.c (revision 256823) @@ -10743,6 +10743,18 @@ cp_parser_statement (cp_parser* parser, "attributes at the beginning of statement are ignored"); } +/* Append ATTR to attribute list ATTRS. */ + +static tree +attr_chainon (tree attrs, tree attr) +{ + if (attrs == error_mark_node) + return error_mark_node; + if (attr == error_mark_node) + return error_mark_node; + return chainon (attrs, attr); +} + /* Parse the label for a labeled-statement, i.e. identifier : @@ -10862,7 +10874,7 @@ cp_parser_label_for_labeled_statement (c else if (!cp_parser_parse_definitely (parser)) ; else - attributes = chainon (attributes, attrs); + attributes = attr_chainon (attributes, attrs); } if (attributes != NULL_TREE) @@ -13194,8 +13206,7 @@ cp_parser_decl_specifier_seq (cp_parser* else { decl_specs->std_attributes - = chainon (decl_specs->std_attributes, - attrs); + = attr_chainon (decl_specs->std_attributes, attrs); if (decl_specs->locations[ds_std_attribute] == 0) decl_specs->locations[ds_std_attribute] = token->location; } @@ -13203,9 +13214,8 @@ cp_parser_decl_specifier_seq (cp_parser* } } - decl_specs->attributes - = chainon (decl_specs->attributes, - attrs); + decl_specs->attributes + = attr_chainon (decl_specs->attributes, attrs); if (decl_specs->locations[ds_attribute] == 0) decl_specs->locations[ds_attribute] = token->location; continue; @@ -18227,7 +18237,7 @@ cp_parser_namespace_definition (cp_parse if (post_ident_attribs) { if (attribs) - attribs = chainon (attribs, post_ident_attribs); + attribs = attr_chainon (attribs, post_ident_attribs); else attribs = post_ident_attribs; } @@ -19401,7 +19411,7 @@ cp_parser_init_declarator (cp_parser* pa decl = grokfield (declarator, decl_specifiers, initializer, !is_non_constant_init, /*asmspec=*/NULL_TREE, - chainon (attributes, prefix_attributes)); + attr_chainon (attributes, prefix_attributes)); if (decl && TREE_CODE (decl) == FUNCTION_DECL) cp_parser_save_default_args (parser, decl); cp_finalize_omp_declare_simd (parser, decl); @@ -20796,9 +20806,9 @@ cp_parser_type_specifier_seq (cp_parser* /* Check for attributes first. */ if (cp_next_tokens_can_be_attribute_p (parser)) { - type_specifier_seq->attributes = - chainon (type_specifier_seq->attributes, - cp_parser_attributes_opt (parser)); + type_specifier_seq->attributes + = attr_chainon (type_specifier_seq->attributes, + cp_parser_attributes_opt (parser)); continue; } @@ -21277,8 +21287,8 @@ cp_parser_parameter_declaration (cp_pars parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ decl_specifiers.attributes - = chainon (decl_specifiers.attributes, - cp_parser_attributes_opt (parser)); + = attr_chainon (decl_specifiers.attributes, + cp_parser_attributes_opt (parser)); /* If the declarator is a template parameter pack, remember that and clear the flag in the declarator itself so we don't get errors @@ -23268,7 +23278,7 @@ cp_parser_member_declaration (cp_parser* which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* Create the bitfield declaration. */ decl = grokbitfield (identifier @@ -23325,7 +23335,7 @@ cp_parser_member_declaration (cp_parser* which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* If it's an `=', then we have a constant-initializer or a pure-specifier. It is not correct to parse the @@ -23439,10 +23449,13 @@ cp_parser_member_declaration (cp_parser* cp_finalize_oacc_routine (parser, decl, false); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } /* If there is any qualification still in effect, clear it now; we will be starting fresh with the next declarator. */ @@ -24554,7 +24567,7 @@ cp_parser_gnu_attributes_opt (cp_parser* cp_parser_skip_to_end_of_statement (parser); /* Add these new attributes to the list. */ - attributes = chainon (attributes, attribute_list); + attributes = attr_chainon (attributes, attribute_list); } return attributes; @@ -29732,7 +29745,7 @@ cp_parser_objc_class_ivars (cp_parser* p which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); if (width) /* Create the bitfield declaration. */ @@ -29749,10 +29762,13 @@ cp_parser_objc_class_ivars (cp_parser* p objc_add_instance_variable (decl); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } token = cp_lexer_peek_token (parser->lexer); @@ -30282,8 +30298,8 @@ cp_parser_objc_struct_declaration (cp_pa which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); - + attributes = attr_chainon (prefix_attributes, attributes); + decl = grokfield (declarator, &declspecs, NULL_TREE, /*init_const_expr_p=*/false, NULL_TREE, attributes); @@ -30292,10 +30308,13 @@ cp_parser_objc_struct_declaration (cp_pa return error_mark_node; /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } DECL_CHAIN (decl) = decls; decls = decl; --- gcc/testsuite/g++.dg/cpp0x/pr83824.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/pr83824.C (revision 256823) @@ -0,0 +1,9 @@ +// PR c++/83824 +// { dg-do compile { target c++11 } } + +void +foo () +{ + if (alignas(1 alignas(1))) // { dg-error "expected" } + ; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-20 Jakub Jelinek <ja...@redhat.com> PR target/83930 * simplify-rtx.c (simplify_binary_operation_1) <case UMOD>: Use UINTVAL (trueop1) instead of INTVAL (op1). * gcc.dg/pr83930.c: New test. --- gcc/simplify-rtx.c (revision 256914) +++ gcc/simplify-rtx.c (revision 256915) @@ -3411,7 +3411,8 @@ simplify_binary_operation_1 (enum rtx_co if (CONST_INT_P (trueop1) && exact_log2 (UINTVAL (trueop1)) > 0) return simplify_gen_binary (AND, mode, op0, - gen_int_mode (INTVAL (op1) - 1, mode)); + gen_int_mode (UINTVAL (trueop1) - 1, + mode)); break; case MOD: --- gcc/testsuite/gcc.dg/pr83930.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83930.c (revision 256915) @@ -0,0 +1,17 @@ +/* PR target/83930 */ +/* { dg-do compile } */ +/* { dg-options "-Og -fno-tree-ccp -w" } */ + +unsigned __attribute__ ((__vector_size__ (16))) v; + +static inline void +bar (unsigned char d) +{ + v /= d; +} + +__attribute__ ((always_inline)) void +foo (void) +{ + bar (4); +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-20 Jakub Jelinek <ja...@redhat.com> PR middle-end/83945 * tree-emutls.c: Include gimplify.h. (lower_emutls_2): New function. (lower_emutls_1): If ADDR_EXPR is a gimple invariant and walk_tree with lower_emutls_2 callback finds some TLS decl in it, unshare_expr it before further processing. * gcc.dg/tls/pr83945.c: New test. --- gcc/tree-emutls.c (revision 256915) +++ gcc/tree-emutls.c (revision 256916) @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. #include "gimple-walk.h" #include "langhooks.h" #include "tree-iterator.h" +#include "gimplify.h" /* Whenever a target does not support thread-local storage (TLS) natively, we can emulate it with some run-time support in libgcc. This will in @@ -429,6 +430,20 @@ gen_emutls_addr (tree decl, struct lower return addr; } +/* Callback for lower_emutls_1, return non-NULL if there is any TLS + VAR_DECL in the subexpressions. */ + +static tree +lower_emutls_2 (tree *ptr, int *walk_subtrees, void *) +{ + tree t = *ptr; + if (TREE_CODE (t) == VAR_DECL) + return DECL_THREAD_LOCAL_P (t) ? t : NULL_TREE; + else if (!EXPR_P (t)) + *walk_subtrees = 0; + return NULL_TREE; +} + /* Callback for walk_gimple_op. D = WI->INFO is a struct lower_emutls_data. Given an operand *PTR within D->STMT, if the operand references a TLS variable, then lower the reference to a call to the runtime. Insert @@ -455,6 +470,13 @@ lower_emutls_1 (tree *ptr, int *walk_sub { bool save_changed; + /* Gimple invariants are shareable trees, so before changing + anything in them if we will need to change anything, unshare + them. */ + if (is_gimple_min_invariant (t) + && walk_tree (&TREE_OPERAND (t, 0), lower_emutls_2, NULL, NULL)) + *ptr = t = unshare_expr (t); + /* If we're allowed more than just is_gimple_val, continue. */ if (!wi->val_only) { --- gcc/testsuite/gcc.dg/tls/pr83945.c (nonexistent) +++ gcc/testsuite/gcc.dg/tls/pr83945.c (revision 256916) @@ -0,0 +1,21 @@ +/* PR middle-end/83945 */ +/* { dg-do compile { target tls } } */ +/* { dg-options "-O2" } */ + +struct S { int a[1]; }; +__thread struct T { int c; } e; +int f; +void bar (int); + +void +foo (int f, int x) +{ + struct S *h = (struct S *) &e.c; + for (;;) + { + int *a = h->a, i; + for (i = x; i; i--) + bar (a[f]); + bar (a[f]); + } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-23 Jakub Jelinek <ja...@redhat.com> PR c++/83958 * decl.c (cp_finish_decomp): Diagnose if reference structure binding refers to incomplete type. * g++.dg/cpp1z/decomp35.C: New test. --- gcc/cp/decl.c (revision 256983) +++ gcc/cp/decl.c (revision 256984) @@ -7435,6 +7435,12 @@ cp_finish_decomp (tree decl, tree first, type = complete_type (TREE_TYPE (type)); if (type == error_mark_node) goto error_out; + if (!COMPLETE_TYPE_P (type)) + { + error_at (loc, "structured binding refers to incomplete type %qT", + type); + goto error_out; + } } tree eltype = NULL_TREE; --- gcc/testsuite/g++.dg/cpp1z/decomp35.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp35.C (revision 256984) @@ -0,0 +1,35 @@ +// PR c++/83958 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +template <typename = void> struct A; +class B; +template <typename, typename, typename = A<>> class C; +template <typename, typename> struct D; +template <typename T, typename U, typename V, typename, typename, typename W> +struct E { + using X = W; + X operator* (); + T operator++ (); + template <typename P, typename R, typename S, typename Q> + bool operator!= (E<P, U, V, R, S, Q>); +}; +template <typename T, typename U, typename> +struct F { + class G; + using H = D<T, U>; + using I = E<G, T, U, G, H, H &>; + class G : public I {}; + G begin (); + G end (); +}; +template <typename T, typename U, typename V> struct C : F<T, U, V> { + using J = F<T, U, V>; + using J::begin; + using J::end; +}; +using K = class L; +struct M { + void foo () { for (auto & [ a ] : m) {} } // { dg-error "incomplete type" } + C<K, B> m; // { dg-warning "only available with" "" { target c++14_down } .-1 } +};
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-23 Jakub Jelinek <ja...@redhat.com> PR sanitizer/83987 * tree.c (cp_free_lang_data): Change DECL_VALUE_EXPR of DECL_OMP_PRIVATIZED_MEMBER vars to error_mark_node. * g++.dg/ubsan/pr83987.C: New test. --- gcc/cp/tree.c (revision 256996) +++ gcc/cp/tree.c (revision 256997) @@ -4844,6 +4844,16 @@ cp_free_lang_data (tree t) from the binding level. */ DECL_CHAIN (t) = NULL_TREE; } + /* Set DECL_VALUE_EXPRs of OpenMP privatized member artificial + decls to error_mark_node. These are DECL_IGNORED_P and after + OpenMP lowering they aren't useful anymore. Clearing DECL_VALUE_EXPR + doesn't work, as expansion could then consider them as something + to be expanded. */ + if (VAR_P (t) + && DECL_LANG_SPECIFIC (t) + && DECL_OMP_PRIVATIZED_MEMBER (t) + && DECL_IGNORED_P (t)) + SET_DECL_VALUE_EXPR (t, error_mark_node); } /* Stub for c-common. Please keep in sync with c-decl.c. --- gcc/testsuite/g++.dg/ubsan/pr83987.C (nonexistent) +++ gcc/testsuite/g++.dg/ubsan/pr83987.C (revision 256997) @@ -0,0 +1,15 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr -O0" } + +struct A { int i; }; +struct B : virtual A { void foo (); }; + +void +B::foo () +{ +#pragma omp sections lastprivate (i) + { + i = 0; + } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-24 Jakub Jelinek <ja...@redhat.com> PR middle-end/83977 * tree-inline.c (tree_function_versioning): Remove "omp declare simd" attributes from DECL_ATTRIBUTES (new_decl) without affecting DECL_ATTRIBUTES (old_decl). * c-c++-common/gomp/pr83977-1.c: New test. * c-c++-common/gomp/pr83977-2.c: New test. * c-c++-common/gomp/pr83977-3.c: New test. * gfortran.dg/gomp/pr83977.f90: New test. --- gcc/tree-inline.c.jj 2017-10-27 22:32:58.102167717 +0200 +++ gcc/tree-inline.c 2018-03-02 21:32:09.804354995 +0100 @@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. #include "cfgloop.h" #include "builtins.h" #include "tree-chkp.h" +#include "attribs.h" /* I'm not real happy about this, but we need to handle gimple and @@ -6024,6 +6025,25 @@ tree_function_versioning (tree old_decl, = copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id, args_to_skip, &vars); + /* Remove omp declare simd attribute from the new attributes. */ + if (tree a = lookup_attribute ("omp declare simd", + DECL_ATTRIBUTES (new_decl))) + { + while (tree a2 = lookup_attribute ("omp declare simd", TREE_CHAIN (a))) + a = a2; + a = TREE_CHAIN (a); + for (tree *p = &DECL_ATTRIBUTES (new_decl); *p != a;) + if (is_attribute_p ("omp declare simd", get_attribute_name (*p))) + *p = TREE_CHAIN (*p); + else + { + tree chain = TREE_CHAIN (*p); + *p = copy_node (*p); + p = &TREE_CHAIN (*p); + *p = chain; + } + } + DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id); BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl; --- gcc/testsuite/gfortran.dg/gomp/pr83977.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/gomp/pr83977.f90 (revision 257023) @@ -0,0 +1,15 @@ +! PR middle-end/83977 +! { dg-do compile } + +integer function foo (a, b) + integer :: a, b +!$omp declare simd uniform(b) linear(ref(a):b) + a = a + 1 +! This function can't be called from simd loops, +! because it violates declare simd restrictions. +! We shouldn't ICE on it though, nor attempt to generate +! simd clones for the *omp_fn* functions. +!$omp parallel + call sub +!$omp end parallel +end --- gcc/testsuite/c-c++-common/gomp/pr83977-1.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr83977-1.c (revision 257023) @@ -0,0 +1,19 @@ +/* PR middle-end/83977 */ +/* { dg-do compile } */ +/* { dg-additional-options "-O2" } */ + +struct S { int a, b, c; }; + +#pragma omp declare simd uniform(z) linear(v:1) +__attribute__((noinline)) static int +foo (int x, int y, struct S z, int u, int v) +{ + return x + y + z.a; +} + +int +bar (int x, int y, int z) +{ + struct S s = { z, 1, 1 }; + return foo (x, y, s, 0, 0); +} --- gcc/testsuite/c-c++-common/gomp/pr83977-2.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr83977-2.c (revision 257023) @@ -0,0 +1,18 @@ +/* PR middle-end/83977 */ +/* { dg-do compile } */ + +void bar (void); + +#pragma omp declare simd uniform (b) linear(a:b) +int +foo (int a, int b) +{ + a = a + 1; +/* This function can't be called from simd loops, + because it violates declare simd restrictions. + We shouldn't ICE on it though, nor attempt to generate + simd clones for the *omp_fn* functions. */ + #pragma omp parallel + bar (); + return a; +} --- gcc/testsuite/c-c++-common/gomp/pr83977-3.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr83977-3.c (revision 257023) @@ -0,0 +1,21 @@ +/* PR middle-end/83977 */ +/* { dg-do compile } */ + +void bar (void); +int foo (int, int) __attribute__((used)); + +#pragma omp declare simd uniform (b) linear(a:b) +int +foo (int a, int b) +{ + a = a + 1; +/* This function can't be called from simd loops, + because it violates declare simd restrictions. + We shouldn't ICE on it though, nor attempt to generate + simd clones for the *omp_fn* functions. */ + #pragma omp parallel + bar (); + return a; +} + +int foo (int, int) __attribute__((unused));
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-25 Jakub Jelinek <ja...@redhat.com> PR c++/84031 * decl.c (find_decomp_class_base): Ignore unnamed bitfields. Ignore recursive calls that return ret. (cp_finish_decomp): Ignore unnamed bitfields. * g++.dg/cpp1z/decomp36.C: New test. --- gcc/cp/decl.c (revision 257056) +++ gcc/cp/decl.c (revision 257057) @@ -7206,7 +7206,9 @@ find_decomp_class_base (location_t loc, { bool member_seen = false; for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) continue; else if (ret) return type; @@ -7245,7 +7247,7 @@ find_decomp_class_base (location_t loc, tree t = find_decomp_class_base (loc, TREE_TYPE (base_binfo), ret); if (t == error_mark_node) return error_mark_node; - if (t != NULL_TREE) + if (t != NULL_TREE && t != ret) { if (ret == type) { @@ -7256,9 +7258,6 @@ find_decomp_class_base (location_t loc, } else if (orig_ret != NULL_TREE) return t; - else if (ret == t) - /* OK, found the same base along another path. We'll complain - in convert_to_base if it's ambiguous. */; else if (ret != NULL_TREE) { error_at (loc, "cannot decompose class type %qT: its base " @@ -7645,7 +7644,9 @@ cp_finish_decomp (tree decl, tree first, goto error_out; } for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field)) - if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) continue; else eltscnt++; @@ -7660,7 +7661,9 @@ cp_finish_decomp (tree decl, tree first, } unsigned int i = 0; for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field)) - if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) != FIELD_DECL + || DECL_ARTIFICIAL (field) + || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))) continue; else { --- gcc/testsuite/g++.dg/cpp1z/decomp36.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp36.C (revision 257057) @@ -0,0 +1,19 @@ +// PR c++/84031 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { unsigned char : 1, a1 : 1, a2 : 2, : 1, a3 : 3; }; +struct B { unsigned char : 1, : 7; }; +struct C : B { constexpr C () : c1 (1), c2 (2), c3 (3) {} unsigned char : 1, c1 : 1, c2 : 2, : 1, c3 : 3; }; +struct D : C { constexpr D () {} unsigned char : 1, : 7; }; + +int +main () +{ + static constexpr A a { 1, 2, 3 }; + const auto &[a1, a2, a3] = a; // { dg-warning "only available with" "" { target c++14_down } } + static_assert (a1 == 1 && a2 == 2 && a3 == 3, ""); + static constexpr D d; + const auto &[d1, d2, d3] = d; // { dg-warning "only available with" "" { target c++14_down } } + static_assert (d1 == 1 && d2 == 2 && d3 == 3, ""); +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-27 Jakub Jelinek <ja...@redhat.com> * c-cppbuiltin.c (c_cpp_builtins): Use ggc_strdup for the fp_suffix argument. (LAZY_HEX_FP_VALUES_CNT): Define. (lazy_hex_fp_values): Allow up to LAZY_HEX_FP_VALUES_CNT lazy hex fp values rather than just 12. (builtin_define_with_hex_fp_value): Likewise. * include/cpplib.h (enum cpp_builtin_type): Change BT_LAST_USER from BT_FIRST_USER + 31 to BT_FIRST_USER + 63. --- gcc/c-family/c-cppbuiltin.c (revision 257117) +++ gcc/c-family/c-cppbuiltin.c (revision 257118) @@ -1119,7 +1119,7 @@ c_cpp_builtins (cpp_reader *pfile) floatn_nx_types[i].extended ? "X" : ""); sprintf (csuffix, "F%d%s", floatn_nx_types[i].n, floatn_nx_types[i].extended ? "x" : ""); - builtin_define_float_constants (prefix, csuffix, "%s", NULL, + builtin_define_float_constants (prefix, ggc_strdup (csuffix), "%s", NULL, FLOATN_NX_TYPE_NODE (i)); } @@ -1566,7 +1566,14 @@ struct GTY(()) lazy_hex_fp_value_struct int digits; const char *fp_suffix; }; -static GTY(()) struct lazy_hex_fp_value_struct lazy_hex_fp_values[12]; +/* Number of the expensive to compute macros we should evaluate lazily. + Each builtin_define_float_constants invocation calls + builtin_define_with_hex_fp_value 4 times and builtin_define_float_constants + is called for FLT, DBL, LDBL and up to NUM_FLOATN_NX_TYPES times for + FLTNN*. */ +#define LAZY_HEX_FP_VALUES_CNT (4 * (3 + NUM_FLOATN_NX_TYPES)) +static GTY(()) struct lazy_hex_fp_value_struct + lazy_hex_fp_values[LAZY_HEX_FP_VALUES_CNT]; static GTY(()) int lazy_hex_fp_value_count; static bool @@ -1611,7 +1618,7 @@ builtin_define_with_hex_fp_value (const char dec_str[64], buf1[256], buf2[256]; /* This is very expensive, so if possible expand them lazily. */ - if (lazy_hex_fp_value_count < 12 + if (lazy_hex_fp_value_count < LAZY_HEX_FP_VALUES_CNT && flag_dump_macros == 0 && !cpp_get_options (parse_in)->traditional) { --- libcpp/include/cpplib.h (revision 257117) +++ libcpp/include/cpplib.h (revision 257118) @@ -719,7 +719,7 @@ enum cpp_builtin_type BT_COUNTER, /* `__COUNTER__' */ BT_HAS_ATTRIBUTE, /* `__has_attribute__(x)' */ BT_FIRST_USER, /* User defined builtin macros. */ - BT_LAST_USER = BT_FIRST_USER + 31 + BT_LAST_USER = BT_FIRST_USER + 63 }; #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-27 Jakub Jelinek <ja...@redhat.com> PR middle-end/84040 * sched-deps.c (sched_macro_fuse_insns): Return immediately if !insn_set. --- gcc/sched-deps.c (revision 257118) +++ gcc/sched-deps.c (revision 257119) @@ -2851,9 +2851,11 @@ sched_macro_fuse_insns (rtx_insn *insn) { rtx insn_set = single_set (insn); + if (!insn_set) + return; + prev = prev_nonnote_nondebug_insn (insn); if (!prev - || !insn_set || !single_set (prev)) return;
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-29 Christoph Spiel <csp...@freenet.de> Jakub Jelinek <ja...@redhat.com> PR libgomp/84096 * omp.h.in (omp_init_nest_lock_with_hint): Use omp_nest_lock_t instead of omp_lock_t. --- libgomp/omp.h.in (revision 257166) +++ libgomp/omp.h.in (revision 257167) @@ -101,7 +101,7 @@ extern void omp_unset_lock (omp_lock_t * extern int omp_test_lock (omp_lock_t *) __GOMP_NOTHROW; extern void omp_init_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; -extern void omp_init_nest_lock_with_hint (omp_lock_t *, omp_lock_hint_t) +extern void omp_init_nest_lock_with_hint (omp_nest_lock_t *, omp_lock_hint_t) __GOMP_NOTHROW; extern void omp_destroy_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW; extern void omp_set_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-30 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/83986 * sched-deps.c (sched_analyze_insn): For frame related insns, add anti dependence against last_pending_memory_flush in addition to pending_jump_insns. * gcc.dg/pr83986.c: New test. --- gcc/sched-deps.c (revision 257202) +++ gcc/sched-deps.c (revision 257203) @@ -2922,6 +2922,8 @@ sched_analyze_insn (struct deps_desc *de = alloc_INSN_LIST (insn, deps->sched_before_next_jump); /* Make sure epilogue insn is scheduled after preceding jumps. */ + add_dependence_list (insn, deps->last_pending_memory_flush, 1, + REG_DEP_ANTI, true); add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI, true); } --- gcc/testsuite/gcc.dg/pr83986.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr83986.c (revision 257203) @@ -0,0 +1,14 @@ +/* PR rtl-optimization/83986 */ +/* { dg-do compile } */ +/* { dg-options "-g -O2 -fsched2-use-superblocks -funwind-tables --param max-pending-list-length=1" } */ + +int v; + +int +foo (int x) +{ + v &= !!v && !!x; + if (v != 0) + foo (0); + return 0; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-31 Jakub Jelinek <ja...@redhat.com> PR preprocessor/69869 * traditional.c (skip_macro_block_comment): Return bool, true if the macro block comment is unterminated. (copy_comment): Use return value from skip_macro_block_comment instead of always false. * gcc.dg/cpp/trad/pr69869.c: New test. --- libcpp/traditional.c (revision 257219) +++ libcpp/traditional.c (revision 257220) @@ -119,8 +119,11 @@ check_output_buffer (cpp_reader *pfile, } /* Skip a C-style block comment in a macro as a result of -CC. - Buffer->cur points to the initial asterisk of the comment. */ -static void + PFILE->buffer->cur points to the initial asterisk of the comment, + change it to point to after the '*' and '/' characters that terminate it. + Return true if the macro has not been termined, in that case set + PFILE->buffer->cur to the end of the buffer. */ +static bool skip_macro_block_comment (cpp_reader *pfile) { const uchar *cur = pfile->buffer->cur; @@ -131,10 +134,15 @@ skip_macro_block_comment (cpp_reader *pf /* People like decorating comments with '*', so check for '/' instead for efficiency. */ - while(! (*cur++ == '/' && cur[-2] == '*') ) - ; + while (! (*cur++ == '/' && cur[-2] == '*')) + if (cur[-1] == '\n') + { + pfile->buffer->cur = cur - 1; + return true; + } pfile->buffer->cur = cur; + return false; } /* CUR points to the asterisk introducing a comment in the current @@ -158,7 +166,7 @@ copy_comment (cpp_reader *pfile, const u buffer->cur = cur; if (pfile->context->prev) - unterminated = false, skip_macro_block_comment (pfile); + unterminated = skip_macro_block_comment (pfile); else unterminated = _cpp_skip_block_comment (pfile); --- gcc/testsuite/gcc.dg/cpp/trad/pr69869.c (nonexistent) +++ gcc/testsuite/gcc.dg/cpp/trad/pr69869.c (revision 257220) @@ -0,0 +1,8 @@ +/* PR preprocessor/69869 */ +/* { dg-do preprocess } */ +/* { dg-options "-traditional-cpp" } */ + +#define C(a,b)a/**/b +C (foo/,**/) +C (foo/,*) +/* { dg-error "unterminated comment" "" {target "*-*-*"} .-1 } */
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-31 Jason Merrill <ja...@redhat.com> Jakub Jelinek <ja...@redhat.com> PR c++/83993 * constexpr.c (cxx_eval_outermost_constant_expr): Build NOP_EXPR around non-constant ADDR_EXPRs rather than clearing TREE_CONSTANT on ADDR_EXPR. * g++.dg/init/pr83993-2.C: New test. --- gcc/cp/constexpr.c (revision 257264) +++ gcc/cp/constexpr.c (revision 257265) @@ -4840,8 +4840,12 @@ cxx_eval_outermost_constant_expr (tree t return error_mark_node; else if (non_constant_p && TREE_CONSTANT (r)) { - /* This isn't actually constant, so unset TREE_CONSTANT. */ - if (EXPR_P (r)) + /* This isn't actually constant, so unset TREE_CONSTANT. + Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires + it to be set if it is invariant address, even when it is not + a valid C++ constant expression. Wrap it with a NOP_EXPR + instead. */ + if (EXPR_P (r) && TREE_CODE (r) != ADDR_EXPR) r = copy_node (r); else if (TREE_CODE (r) == CONSTRUCTOR) r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r); --- gcc/testsuite/g++.dg/init/pr83993-2.C (nonexistent) +++ gcc/testsuite/g++.dg/init/pr83993-2.C (revision 257265) @@ -0,0 +1,14 @@ +// PR c++/83993 +// { dg-do compile } +// { dg-options "-w" } + +int a[5]; +extern int b[]; +int *const c = &a[6]; +int *const d = &b[1]; + +int +foo () +{ + return c[-4] + d[-1]; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-01-31 Jakub Jelinek <ja...@redhat.com> PR fortran/84116 * openmp.c (gfc_match_omp_clauses): If all the linear gfc_match_omp_variable_list calls failed, don't gfc_free_omp_namelist nor set *head = NULL. Formatting fixes. * gfortran.dg/gomp/pr84116.f90: New test. --- gcc/fortran/openmp.c (revision 257265) +++ gcc/fortran/openmp.c (revision 257266) @@ -1318,23 +1318,21 @@ gfc_match_omp_clauses (gfc_omp_clauses * else if (gfc_match_omp_variable_list (" val (", &c->lists[OMP_LIST_LINEAR], false, NULL, &head) - == MATCH_YES) + == MATCH_YES) linear_op = OMP_LINEAR_VAL; else if (gfc_match_omp_variable_list (" uval (", &c->lists[OMP_LIST_LINEAR], false, NULL, &head) - == MATCH_YES) + == MATCH_YES) linear_op = OMP_LINEAR_UVAL; else if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_LINEAR], false, &end_colon, &head) - == MATCH_YES) + == MATCH_YES) linear_op = OMP_LINEAR_DEFAULT; else { - gfc_free_omp_namelist (*head); gfc_current_locus = old_loc; - *head = NULL; break; } if (linear_op != OMP_LINEAR_DEFAULT) --- gcc/testsuite/gfortran.dg/gomp/pr84116.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/gomp/pr84116.f90 (revision 257266) @@ -0,0 +1,12 @@ +! PR fortran/84116 +! { dg-do compile } + +program pr84116 + integer :: i, j + !$omp simd linear ((i)) ! { dg-error "Syntax error" } + do i = 1, 2 + end do + !$omp simd linear () ! { dg-error "Syntax error" } + do j = 1, 2 + end do +end
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-01 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/81661 PR tree-optimization/84117 * tree-eh.h (rewrite_to_non_trapping_overflow): Declare. * tree-eh.c: Include gimplify.h. (find_trapping_overflow, replace_trapping_overflow, rewrite_to_non_trapping_overflow): New functions. * tree-vect-loop.c: Include tree-eh.h. (vect_get_loop_niters): Use rewrite_to_non_trapping_overflow. * gcc.dg/pr81661.c: New test. * gfortran.dg/pr84117.f90: New test. --- gcc/tree-eh.c (revision 257283) +++ gcc/tree-eh.c (revision 257284) @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. #include "cfgloop.h" #include "gimple-low.h" #include "asan.h" +#include "gimplify.h" /* In some instances a tree and a gimple need to be stored in a same table, i.e. in hash tables. This is a structure to do this. */ @@ -2722,6 +2723,91 @@ tree_could_trap_p (tree expr) } } +/* Return non-NULL if there is an integer operation with trapping overflow + we can rewrite into non-trapping. Called via walk_tree from + rewrite_to_non_trapping_overflow. */ + +static tree +find_trapping_overflow (tree *tp, int *walk_subtrees, void *data) +{ + if (EXPR_P (*tp) + && !operation_no_trapping_overflow (TREE_TYPE (*tp), TREE_CODE (*tp))) + return *tp; + if (IS_TYPE_OR_DECL_P (*tp) + || (TREE_CODE (*tp) == SAVE_EXPR && data == NULL)) + *walk_subtrees = 0; + return NULL_TREE; +} + +/* Rewrite selected operations into unsigned arithmetics, so that they + don't trap on overflow. */ + +static tree +replace_trapping_overflow (tree *tp, int *walk_subtrees, void *data) +{ + if (find_trapping_overflow (tp, walk_subtrees, data)) + { + tree type = TREE_TYPE (*tp); + tree utype = unsigned_type_for (type); + *walk_subtrees = 0; + int len = TREE_OPERAND_LENGTH (*tp); + for (int i = 0; i < len; ++i) + walk_tree (&TREE_OPERAND (*tp, i), replace_trapping_overflow, + data, (hash_set<tree> *) data); + + if (TREE_CODE (*tp) == ABS_EXPR) + { + tree op = TREE_OPERAND (*tp, 0); + op = save_expr (op); + /* save_expr skips simple arithmetics, which is undesirable + here, if it might trap due to flag_trapv. We need to + force a SAVE_EXPR in the COND_EXPR condition, to evaluate + it before the comparison. */ + if (EXPR_P (op) + && TREE_CODE (op) != SAVE_EXPR + && walk_tree (&op, find_trapping_overflow, NULL, NULL)) + { + op = build1_loc (EXPR_LOCATION (op), SAVE_EXPR, type, op); + TREE_SIDE_EFFECTS (op) = 1; + } + /* Change abs (op) to op < 0 ? -op : op and handle the NEGATE_EXPR + like other signed integer trapping operations. */ + tree cond = fold_build2 (LT_EXPR, boolean_type_node, + op, build_int_cst (type, 0)); + tree neg = fold_build1 (NEGATE_EXPR, utype, + fold_convert (utype, op)); + *tp = fold_build3 (COND_EXPR, type, cond, + fold_convert (type, neg), op); + } + else + { + TREE_TYPE (*tp) = utype; + len = TREE_OPERAND_LENGTH (*tp); + for (int i = 0; i < len; ++i) + TREE_OPERAND (*tp, i) + = fold_convert (utype, TREE_OPERAND (*tp, i)); + *tp = fold_convert (type, *tp); + } + } + return NULL_TREE; +} + +/* If any subexpression of EXPR can trap due to -ftrapv, rewrite it + using unsigned arithmetics to avoid traps in it. */ + +tree +rewrite_to_non_trapping_overflow (tree expr) +{ + if (!flag_trapv) + return expr; + hash_set<tree> pset; + if (!walk_tree (&expr, find_trapping_overflow, &pset, &pset)) + return expr; + expr = unshare_expr (expr); + hash_set<tree> pset2; + walk_tree (&expr, replace_trapping_overflow, &pset2, &pset2); + return expr; +} /* Helper for stmt_could_throw_p. Return true if STMT (assumed to be a an assignment or a conditional) may throw. */ --- gcc/tree-eh.h (revision 257283) +++ gcc/tree-eh.h (revision 257284) @@ -37,6 +37,7 @@ extern bool operation_could_trap_helper_ bool, tree, bool *); extern bool operation_could_trap_p (enum tree_code, bool, bool, tree); extern bool tree_could_trap_p (tree); +extern tree rewrite_to_non_trapping_overflow (tree); extern bool stmt_could_throw_p (gimple *); extern bool tree_could_throw_p (tree); extern bool stmt_can_throw_external (gimple *); --- gcc/tree-vect-loop.c (revision 257283) +++ gcc/tree-vect-loop.c (revision 257284) @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. #include "cgraph.h" #include "tree-cfg.h" #include "tree-if-conv.h" +#include "tree-eh.h" /* Loop Vectorization Pass. @@ -1055,7 +1056,8 @@ vect_get_loop_niters (struct loop *loop, may_be_zero)); else niter = fold_build3 (COND_EXPR, TREE_TYPE (niter), may_be_zero, - build_int_cst (TREE_TYPE (niter), 0), niter); + build_int_cst (TREE_TYPE (niter), 0), + rewrite_to_non_trapping_overflow (niter)); may_be_zero = NULL_TREE; } --- gcc/testsuite/gcc.dg/pr81661.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr81661.c (revision 257284) @@ -0,0 +1,12 @@ +/* PR tree-optimization/81661 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -ftrapv" } */ + +int a, b, c; + +void +foo (void) +{ + while (a + c > b) + a--; +} --- gcc/testsuite/gfortran.dg/pr84117.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/pr84117.f90 (revision 257284) @@ -0,0 +1,7 @@ +! PR tree-optimization/84117 +! { dg-do compile } +! { dg-options "-O3 -ftrapv" } + FUNCTION pw_integral_aa ( cc ) RESULT ( integral_value ) + COMPLEX(KIND=8), DIMENSION(:), POINTER :: cc + integral_value = accurate_sum ( CONJG ( cc (:) ) * cc (:) ) + END FUNCTION pw_integral_aa
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-07 Jakub Jelinek <ja...@redhat.com> * tree-eh.c (operation_could_trap_helper_p): Ignore honor_trapv for *DIV_EXPR and *MOD_EXPR. --- gcc/tree-eh.c (revision 257449) +++ gcc/tree-eh.c (revision 257450) @@ -2436,7 +2436,7 @@ operation_could_trap_helper_p (enum tree case ROUND_MOD_EXPR: case TRUNC_MOD_EXPR: case RDIV_EXPR: - if (honor_snans || honor_trapv) + if (honor_snans) return true; if (fp_operation) return flag_trapping_math;
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-07 Jakub Jelinek <ja...@redhat.com> PR c++/84082 * parser.c (cp_parser_dot_deref_incomplete): New function. (cp_parser_postfix_dot_deref_expression): Use it. * g++.dg/template/incomplete11.C: New test. * g++.dg/parse/crash67.C: Expect an incomplete type diagnostics too. --- gcc/cp/parser.c (revision 257465) +++ gcc/cp/parser.c (revision 257466) @@ -7252,6 +7252,60 @@ cp_parser_postfix_open_square_expression return postfix_expression; } +/* A subroutine of cp_parser_postfix_dot_deref_expression. Handle dot + dereference of incomplete type, returns true if error_mark_node should + be returned from caller, otherwise adjusts *SCOPE, *POSTFIX_EXPRESSION + and *DEPENDENT_P. */ + +bool +cp_parser_dot_deref_incomplete (tree *scope, cp_expr *postfix_expression, + bool *dependent_p) +{ + /* In a template, be permissive by treating an object expression + of incomplete type as dependent (after a pedwarn). */ + diagnostic_t kind = (processing_template_decl + && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR); + + switch (TREE_CODE (*postfix_expression)) + { + case CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case STATIC_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case IMPLICIT_CONV_EXPR: + case VIEW_CONVERT_EXPR: + case NON_LVALUE_EXPR: + kind = DK_ERROR; + break; + case OVERLOAD: + /* Don't emit any diagnostic for OVERLOADs. */ + kind = DK_IGNORED; + break; + default: + /* Avoid clobbering e.g. DECLs. */ + if (!EXPR_P (*postfix_expression)) + kind = DK_ERROR; + break; + } + + if (kind == DK_IGNORED) + return false; + + location_t exploc = location_of (*postfix_expression); + cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind); + if (!MAYBE_CLASS_TYPE_P (*scope)) + return true; + if (kind == DK_ERROR) + *scope = *postfix_expression = error_mark_node; + else if (processing_template_decl) + { + *dependent_p = true; + *scope = TREE_TYPE (*postfix_expression) = NULL_TREE; + } + return false; +} + /* A subroutine of cp_parser_postfix_expression that also gets hijacked by cp_parser_builtin_offsetof. We're looking for @@ -7316,23 +7370,9 @@ cp_parser_postfix_dot_deref_expression ( { scope = complete_type (scope); if (!COMPLETE_TYPE_P (scope) - /* Avoid clobbering e.g. OVERLOADs or DECLs. */ - && EXPR_P (postfix_expression)) - { - /* In a template, be permissive by treating an object expression - of incomplete type as dependent (after a pedwarn). */ - diagnostic_t kind = (processing_template_decl - ? DK_PEDWARN - : DK_ERROR); - cxx_incomplete_type_diagnostic - (location_of (postfix_expression), - postfix_expression, scope, kind); - if (processing_template_decl) - { - dependent_p = true; - scope = TREE_TYPE (postfix_expression) = NULL_TREE; - } - } + && cp_parser_dot_deref_incomplete (&scope, &postfix_expression, + &dependent_p)) + return error_mark_node; } if (!dependent_p) --- gcc/testsuite/g++.dg/parse/crash67.C (revision 257465) +++ gcc/testsuite/g++.dg/parse/crash67.C (revision 257466) @@ -3,4 +3,4 @@ class x0; template <x1> x2() { // { dg-error "declared|type" } -x0 x3 = x3. // { dg-error "expected" } +x0 x3 = x3. // { dg-error "expected|incomplete type" } --- gcc/testsuite/g++.dg/template/incomplete11.C (nonexistent) +++ gcc/testsuite/g++.dg/template/incomplete11.C (revision 257466) @@ -0,0 +1,10 @@ +// PR c++/84082 +// { dg-do compile } +// { dg-options "" } + +struct A; + +template<typename> void foo() +{ + static int a[A().operator=(A())]; // { dg-error "invalid use of incomplete type 'struct A'" } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-09 Marek Polacek <pola...@redhat.com> Jakub Jelinek <ja...@redhat.com> PR c++/83659 * fold-const.c (fold_indirect_ref_1): Use VECTOR_TYPE_P macro. Formatting fixes. Verify first that tree_fits_shwi_p (op01). Sync some changes from cxx_fold_indirect_ref. * constexpr.c (cxx_fold_indirect_ref): Sync some changes from fold_indirect_ref_1. Verify first that tree_fits_shwi_p (op01). Formatting fixes. * g++.dg/torture/pr83659.C: New test. --- gcc/fold-const.c (revision 257511) +++ gcc/fold-const.c (revision 257512) @@ -14082,6 +14082,7 @@ fold_indirect_ref_1 (location_t loc, tre { tree op = TREE_OPERAND (sub, 0); tree optype = TREE_TYPE (op); + /* *&CONST_DECL -> to the value of the const decl. */ if (TREE_CODE (op) == CONST_DECL) return DECL_INITIAL (op); @@ -14115,12 +14116,13 @@ fold_indirect_ref_1 (location_t loc, tre && type == TREE_TYPE (optype)) return fold_build1_loc (loc, REALPART_EXPR, type, op); /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */ - else if (TREE_CODE (optype) == VECTOR_TYPE + else if (VECTOR_TYPE_P (optype) && type == TREE_TYPE (optype)) { tree part_width = TYPE_SIZE (type); tree index = bitsize_int (0); - return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, + index); } } @@ -14138,8 +14140,17 @@ fold_indirect_ref_1 (location_t loc, tre op00type = TREE_TYPE (op00); /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ - if (TREE_CODE (op00type) == VECTOR_TYPE - && type == TREE_TYPE (op00type)) + if (VECTOR_TYPE_P (op00type) + && type == TREE_TYPE (op00type) + /* POINTER_PLUS_EXPR second operand is sizetype, unsigned, + but we want to treat offsets with MSB set as negative. + For the code below negative offsets are invalid and + TYPE_SIZE of the element is something unsigned, so + check whether op01 fits into HOST_WIDE_INT, which + implies it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and + then just use unsigned HOST_WIDE_INT because we want to treat + the value as unsigned. */ + && tree_fits_shwi_p (op01)) { tree part_width = TYPE_SIZE (type); unsigned HOST_WIDE_INT max_offset --- gcc/cp/constexpr.c (revision 257511) +++ gcc/cp/constexpr.c (revision 257512) @@ -2966,9 +2966,9 @@ cxx_eval_vec_init (const constexpr_ctx * static tree cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) { - tree sub, subtype; + tree sub = op0; + tree subtype; - sub = op0; STRIP_NOPS (sub); subtype = TREE_TYPE (sub); if (!POINTER_TYPE_P (subtype)) @@ -3023,7 +3023,8 @@ cxx_fold_indirect_ref (location_t loc, t { tree part_width = TYPE_SIZE (type); tree index = bitsize_int (0); - return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, + index); } /* Also handle conversion to an empty base class, which is represented with a NOP_EXPR. */ @@ -3063,19 +3064,31 @@ cxx_fold_indirect_ref (location_t loc, t /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ if (VECTOR_TYPE_P (op00type) && (same_type_ignoring_top_level_qualifiers_p - (type, TREE_TYPE (op00type)))) + (type, TREE_TYPE (op00type))) + /* POINTER_PLUS_EXPR second operand is sizetype, unsigned, + but we want to treat offsets with MSB set as negative. + For the code below negative offsets are invalid and + TYPE_SIZE of the element is something unsigned, so + check whether op01 fits into HOST_WIDE_INT, which + implies it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and + then just use unsigned HOST_WIDE_INT because we want to treat + the value as unsigned. */ + && tree_fits_shwi_p (op01)) { - HOST_WIDE_INT offset = tree_to_shwi (op01); tree part_width = TYPE_SIZE (type); - unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT; - unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; - tree index = bitsize_int (indexi); - - if (offset / part_widthi < TYPE_VECTOR_SUBPARTS (op00type)) - return fold_build3_loc (loc, - BIT_FIELD_REF, type, op00, - part_width, index); - + unsigned HOST_WIDE_INT max_offset + = (tree_to_uhwi (part_width) / BITS_PER_UNIT + * TYPE_VECTOR_SUBPARTS (op00type)); + if (tree_int_cst_sign_bit (op01) == 0 + && compare_tree_int (op01, max_offset) == -1) + { + unsigned HOST_WIDE_INT offset = tree_to_uhwi (op01); + unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; + tree index = bitsize_int (indexi); + return fold_build3_loc (loc, + BIT_FIELD_REF, type, op00, + part_width, index); + } } /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ else if (TREE_CODE (op00type) == COMPLEX_TYPE @@ -3132,7 +3145,8 @@ cxx_fold_indirect_ref (location_t loc, t { tree type_domain; tree min_val = size_zero_node; - tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); + tree newsub + = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); if (newsub) sub = newsub; else --- gcc/testsuite/g++.dg/torture/pr83659.C (nonexistent) +++ gcc/testsuite/g++.dg/torture/pr83659.C (revision 257512) @@ -0,0 +1,18 @@ +// PR c++/83659 +// { dg-do compile } + +typedef int V __attribute__ ((__vector_size__ (16))); +V a; +V b[2]; + +int +foo () +{ + return reinterpret_cast <int *> (&a)[-1] += 1; +} + +int +bar () +{ + return reinterpret_cast <int *> (&a[1])[-1]; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-09 Jakub Jelinek <ja...@redhat.com> PR sanitizer/84285 * gcc.c (STATIC_LIBASAN_LIBS, STATIC_LIBTSAN_LIBS, STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS): Handle -static like -static-lib*san. --- gcc/gcc.c (revision 257514) +++ gcc/gcc.c (revision 257515) @@ -684,7 +684,7 @@ proper position among the other output f #ifndef LIBASAN_SPEC #define STATIC_LIBASAN_LIBS \ - " %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)}" + " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}" #ifdef LIBASAN_EARLY_SPEC #define LIBASAN_SPEC STATIC_LIBASAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -702,7 +702,7 @@ proper position among the other output f #ifndef LIBTSAN_SPEC #define STATIC_LIBTSAN_LIBS \ - " %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)}" + " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}" #ifdef LIBTSAN_EARLY_SPEC #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -720,7 +720,7 @@ proper position among the other output f #ifndef LIBLSAN_SPEC #define STATIC_LIBLSAN_LIBS \ - " %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}" + " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}" #ifdef LIBLSAN_EARLY_SPEC #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -738,7 +738,7 @@ proper position among the other output f #ifndef LIBUBSAN_SPEC #define STATIC_LIBUBSAN_LIBS \ - " %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}" + " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}" #ifdef HAVE_LD_STATIC_DYNAMIC #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \ "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-10 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/84308 * shrink-wrap.c (spread_components): Release todo vector. --- gcc/shrink-wrap.c (revision 257543) +++ gcc/shrink-wrap.c (revision 257544) @@ -1370,6 +1370,8 @@ spread_components (sbitmap components) bitmap_clear_bit (seen, bb->index); } + todo.release (); + /* Finally, mark everything not not needed both forwards and backwards. */ FOR_EACH_BB_FN (bb, cfun)
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-10 Jakub Jelinek <ja...@redhat.com> PR sanitizer/83987 * omp-low.c (maybe_remove_omp_member_access_dummy_vars, remove_member_access_dummy_vars): New functions. (lower_omp_for, lower_omp_taskreg, lower_omp_target, lower_omp_1, execute_lower_omp): Use them. * tree.c (cp_free_lang_data): Revert 2018-01-23 change. * g++.dg/ubsan/pr83987-2.C: New test. --- gcc/omp-low.c (revision 257544) +++ gcc/omp-low.c (revision 257545) @@ -3208,6 +3208,43 @@ scan_omp (gimple_seq *body_p, omp_contex /* Re-gimplification and code generation routines. */ +/* Remove omp_member_access_dummy_var variables from gimple_bind_vars + of BIND if in a method. */ + +static void +maybe_remove_omp_member_access_dummy_vars (gbind *bind) +{ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + { + tree vars = gimple_bind_vars (bind); + for (tree *pvar = &vars; *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + gimple_bind_set_vars (bind, vars); + } +} + +/* Remove omp_member_access_dummy_var variables from BLOCK_VARS of + block and its subblocks. */ + +static void +remove_member_access_dummy_vars (tree block) +{ + for (tree *pvar = &BLOCK_VARS (block); *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + + for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block)) + remove_member_access_dummy_vars (block); +} + /* If a context was created for STMT when it was scanned, return it. */ static omp_context * @@ -6961,6 +6998,7 @@ lower_omp_for (gimple_stmt_iterator *gsi pop_gimplify_context (new_stmt); gimple_bind_append_vars (new_stmt, ctx->block_vars); + maybe_remove_omp_member_access_dummy_vars (new_stmt); BLOCK_VARS (block) = gimple_bind_vars (new_stmt); if (BLOCK_VARS (block)) TREE_USED (block) = 1; @@ -7413,6 +7451,7 @@ lower_omp_taskreg (gimple_stmt_iterator /* Declare all the variables created by mapping and the variables declared in the scope of the parallel body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (par_bind); record_vars_into (gimple_bind_vars (par_bind), child_fn); if (ctx->record_type) @@ -7781,6 +7820,7 @@ lower_omp_target (gimple_stmt_iterator * /* Declare all the variables created by mapping and the variables declared in the scope of the target body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (tgt_bind); record_vars_into (gimple_bind_vars (tgt_bind), child_fn); } @@ -8772,6 +8812,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p break; case GIMPLE_BIND: lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx); + maybe_remove_omp_member_access_dummy_vars (as_a <gbind *> (stmt)); break; case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: @@ -8976,6 +9017,16 @@ execute_lower_omp (void) all_contexts = NULL; } BITMAP_FREE (task_shared_vars); + + /* If current function is a method, remove artificial dummy VAR_DECL created + for non-static data member privatization, they aren't needed for + debuginfo nor anything else, have been already replaced everywhere in the + IL and cause problems with LTO. */ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl)); return 0; } --- gcc/cp/tree.c (revision 257544) +++ gcc/cp/tree.c (revision 257545) @@ -4844,16 +4844,6 @@ cp_free_lang_data (tree t) from the binding level. */ DECL_CHAIN (t) = NULL_TREE; } - /* Set DECL_VALUE_EXPRs of OpenMP privatized member artificial - decls to error_mark_node. These are DECL_IGNORED_P and after - OpenMP lowering they aren't useful anymore. Clearing DECL_VALUE_EXPR - doesn't work, as expansion could then consider them as something - to be expanded. */ - if (VAR_P (t) - && DECL_LANG_SPECIFIC (t) - && DECL_OMP_PRIVATIZED_MEMBER (t) - && DECL_IGNORED_P (t)) - SET_DECL_VALUE_EXPR (t, error_mark_node); } /* Stub for c-common. Please keep in sync with c-decl.c. --- gcc/testsuite/g++.dg/ubsan/pr83987-2.C (nonexistent) +++ gcc/testsuite/g++.dg/ubsan/pr83987-2.C (revision 257545) @@ -0,0 +1,24 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr" } + +struct A +{ + int i; +}; + +struct B : virtual A +{ + void foo(); +}; + +void B::foo() +{ +#pragma omp parallel + { + #pragma omp sections lastprivate (i) + { + i = 0; + } + } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-12 Jakub Jelinek <ja...@redhat.com> PR c++/84341 * parser.c (cp_parser_binary_expression): Use build_min instead of build2_loc to build the no_toplevel_fold_p toplevel binary expression. * c-c++-common/gomp/pr84341.c: New test. --- gcc/cp/parser.c (revision 257606) +++ gcc/cp/parser.c (revision 257607) @@ -9330,12 +9330,14 @@ cp_parser_binary_expression (cp_parser* if (no_toplevel_fold_p && lookahead_prec <= current.prec && sp == stack) - current.lhs = build2_loc (combined_loc, - current.tree_type, - TREE_CODE_CLASS (current.tree_type) - == tcc_comparison - ? boolean_type_node : TREE_TYPE (current.lhs), - current.lhs, rhs); + { + current.lhs + = build_min (current.tree_type, + TREE_CODE_CLASS (current.tree_type) == tcc_comparison + ? boolean_type_node : TREE_TYPE (current.lhs), + current.lhs.get_value (), rhs.get_value ()); + SET_EXPR_LOCATION (current.lhs, combined_loc); + } else { current.lhs = build_x_binary_op (combined_loc, current.tree_type, --- gcc/testsuite/c-c++-common/gomp/pr84341.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr84341.c (revision 257607) @@ -0,0 +1,10 @@ +/* PR c++/84341 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +void +foo (int i) +{ + #pragma omp atomic + i = &i + 1; /* { dg-error "invalid form of" } */ +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-13 Jakub Jelinek <ja...@redhat.com> PR c/82210 * stor-layout.c (place_field): For variable length fields, adjust offset_align afterwards not just based on the field's alignment, but also on the size. * gcc.c-torture/execute/pr82210.c: New test. --- gcc/stor-layout.c (revision 257634) +++ gcc/stor-layout.c (revision 257635) @@ -1622,6 +1622,30 @@ place_field (record_layout_info rli, tre = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field)); rli->bitpos = bitsize_zero_node; rli->offset_align = MIN (rli->offset_align, desired_align); + + if (!multiple_of_p (bitsizetype, DECL_SIZE (field), + bitsize_int (rli->offset_align))) + { + tree type = strip_array_types (TREE_TYPE (field)); + /* The above adjusts offset_align just based on the start of the + field. The field might not have a size that is a multiple of + that offset_align though. If the field is an array of fixed + sized elements, assume there can be any multiple of those + sizes. If it is a variable length aggregate or array of + variable length aggregates, assume worst that the end is + just BITS_PER_UNIT aligned. */ + if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) + { + if (TREE_INT_CST_LOW (TYPE_SIZE (type))) + { + unsigned HOST_WIDE_INT sz + = least_bit_hwi (TREE_INT_CST_LOW (TYPE_SIZE (type))); + rli->offset_align = MIN (rli->offset_align, sz); + } + } + else + rli->offset_align = MIN (rli->offset_align, BITS_PER_UNIT); + } } else if (targetm.ms_bitfield_layout_p (rli->t)) { --- gcc/testsuite/gcc.c-torture/execute/pr82210.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/execute/pr82210.c (revision 257635) @@ -0,0 +1,26 @@ +/* PR c/82210 */ + +void +foo (int size) +{ + int i; + struct S { + __attribute__((aligned (16))) struct T { short c; } a[size]; + int b[size]; + } s; + + for (i = 0; i < size; i++) + s.a[i].c = 0x1234; + for (i = 0; i < size; i++) + s.b[i] = 0; + for (i = 0; i < size; i++) + if (s.a[i].c != 0x1234 || s.b[i] != 0) + __builtin_abort (); +} + +int +main () +{ + foo (15); + return 0; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-16 Marek Polacek <pola...@redhat.com> Jakub Jelinek <ja...@redhat.com> PR c++/84192 * constexpr.c (cxx_eval_constant_expression) <case RETURN_EXPR>: Don't set *jump_target to anything if jump_target is NULL. * g++.dg/cpp1y/constexpr-84192.C: New test. --- gcc/cp/constexpr.c (revision 257769) +++ gcc/cp/constexpr.c (revision 257770) @@ -4254,7 +4254,16 @@ cxx_eval_constant_expression (const cons r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, non_constant_p, overflow_p); - *jump_target = t; + if (jump_target) + *jump_target = t; + else + { + /* Can happen with ({ return true; }) && false; passed to + maybe_constant_value. There is nothing to jump over in this + case, and the bug will be diagnosed later. */ + gcc_assert (ctx->quiet); + *non_constant_p = true; + } break; case SAVE_EXPR: --- gcc/testsuite/g++.dg/cpp1y/constexpr-84192.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1y/constexpr-84192.C (revision 257770) @@ -0,0 +1,41 @@ +// PR c++/84192 +// { dg-do compile { target c++14 } } +// { dg-options "" } + +bool +f1 () +{ + return ({ return true; }) && false; // { dg-error "could not convert" } +} + +void +f2 () +{ + for (;;) + constexpr bool b = ({ break; false; }) && false; // { dg-error "statement is not a constant expression" } +} + +constexpr bool +f3 (int n) +{ + bool b = false; + for (int i = 0; i < n; i++) + b = ({ break; }); // { dg-error "void value not ignored as it ought to be" } + return b; +} + +constexpr bool b = f3 (4); + +bool +f4 () +{ + constexpr bool b = ({ return true; }) && false; // { dg-error "could not convert" } + return false; +} + +constexpr bool +f5 (int x) +{ + constexpr bool b = ({ switch (x) case 0: true; }) && false; // { dg-error "could not convert" } + return false; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-16 Jakub Jelinek <ja...@redhat.com> PR fortran/84418 * trans-openmp.c (gfc_trans_omp_clauses): For OMP_CLAUSE_LINEAR_REF kind set OMP_CLAUSE_LINEAR_STEP to TYPE_SIZE_UNIT times last_step. * libgomp.fortran/pr84418-1.f90: New test. * libgomp.fortran/pr84418-2.f90: New test. --- gcc/fortran/trans-openmp.c (revision 257770) +++ gcc/fortran/trans-openmp.c (revision 257771) @@ -1949,9 +1949,32 @@ gfc_trans_omp_clauses (stmtblock_t *bloc } else { - tree type = gfc_typenode_for_spec (&n->sym->ts); - OMP_CLAUSE_LINEAR_STEP (node) - = fold_convert (type, last_step); + if (kind == OMP_CLAUSE_LINEAR_REF) + { + tree type; + if (n->sym->attr.flavor == FL_PROCEDURE) + { + type = gfc_get_function_type (n->sym); + type = build_pointer_type (type); + } + else + type = gfc_sym_type (n->sym); + if (POINTER_TYPE_P (type)) + type = TREE_TYPE (type); + /* Otherwise to be determined what exactly + should be done. */ + tree t = fold_convert (sizetype, last_step); + t = size_binop (MULT_EXPR, t, + TYPE_SIZE_UNIT (type)); + OMP_CLAUSE_LINEAR_STEP (node) = t; + } + else + { + tree type + = gfc_typenode_for_spec (&n->sym->ts); + OMP_CLAUSE_LINEAR_STEP (node) + = fold_convert (type, last_step); + } } if (n->sym->attr.dimension || n->sym->attr.allocatable) OMP_CLAUSE_LINEAR_ARRAY (node) = 1; --- libgomp/testsuite/libgomp.fortran/pr84418-1.f90 (nonexistent) +++ libgomp/testsuite/libgomp.fortran/pr84418-1.f90 (revision 257771) @@ -0,0 +1,26 @@ +! PR fortran/84418 +! { dg-do run { target vect_simd_clones } } +! { dg-options "-fno-inline" } +! { dg-additional-options "-msse2" { target sse2_runtime } } +! { dg-additional-options "-mavx" { target avx_runtime } } + + real :: a(1024), b(1024), c(1024) + integer :: i + do i = 1, 1024 + a(i) = 0.5 * i + b(i) = 1.5 * i + end do + !$omp simd + do i = 1, 1024 + c(i) = foo (a(i), b(i)) + end do + do i = 1, 1024 + if (c(i).ne.(2 * i)) call abort + end do +contains + real function foo (x, y) + real :: x, y + !$omp declare simd linear (ref (x, y)) + foo = x + y + end function +end --- libgomp/testsuite/libgomp.fortran/pr84418-2.f90 (nonexistent) +++ libgomp/testsuite/libgomp.fortran/pr84418-2.f90 (revision 257771) @@ -0,0 +1,35 @@ +! PR fortran/84418 +! { dg-do run { target vect_simd_clones } } +! { dg-options "-fno-inline" } +! { dg-additional-options "-msse2" { target sse2_runtime } } +! { dg-additional-options "-mavx" { target avx_runtime } } + + type p + integer :: i, j + end type + type(p) :: a(1024) + integer :: b(4,1024), c(1024) + integer :: i + do i = 1, 1024 + a(i)%i = 2 * i + a(i)%j = 3 * i + b(1,i) = 4 * i + b(2,i) = 5 * i + b(3,i) = 6 * i + b(4,i) = 7 * i + end do + !$omp simd + do i = 1, 1024 + c(i) = foo (a(i), b(:,i)) + end do + do i = 1, 1024 + if (c(i).ne.(6 * i)) call abort + end do +contains + function foo (x, y) + type (p) :: x + integer :: y(4), foo + !$omp declare simd linear (ref (x, y)) + foo = x%i + y(1) + end function +end
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-16 Jakub Jelinek <ja...@redhat.com> PR ipa/84425 * ipa-inline.c (inline_small_functions): Fix a typo. * gcc.c-torture/compile/pr84425.c: New test. --- gcc/ipa-inline.c (revision 257771) +++ gcc/ipa-inline.c (revision 257772) @@ -1773,7 +1773,7 @@ inline_small_functions (void) struct cgraph_node *n2; int id = dfs->scc_no + 1; for (n2 = node; n2; - n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle) + n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle) { struct inline_summary *info2 = inline_summaries->get (n2); if (info2->scc_no) --- gcc/testsuite/gcc.c-torture/compile/pr84425.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr84425.c (revision 257772) @@ -0,0 +1,17 @@ +/* PR ipa/84425 */ + +void bar (int); + +void +foo (int x) +{ + if (x < 5) + bar (x); +} + +__attribute__((optimize(0))) void +bar (int x) +{ + if (x > 10) + foo (x); +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-19 Jakub Jelinek <ja...@redhat.com> PR c++/84430 * constexpr.c (potential_constant_expression_1): Handle OMP_SIMD. * g++.dg/gomp/pr84430.C: New test. --- gcc/cp/constexpr.c (revision 257819) +++ gcc/cp/constexpr.c (revision 257820) @@ -5604,6 +5604,7 @@ potential_constant_expression_1 (tree t, case OMP_PARALLEL: case OMP_TASK: case OMP_FOR: + case OMP_SIMD: case OMP_DISTRIBUTE: case OMP_TASKLOOP: case OMP_TEAMS: --- gcc/testsuite/g++.dg/gomp/pr84430.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr84430.C (revision 257820) @@ -0,0 +1,12 @@ +// PR c++/84430 +// { dg-do compile { target c++11 } } + +void +foo () +{ + auto a = [] { + #pragma omp simd + for (int i = 0; i < 10; ++i) + ; + }; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-19 Jakub Jelinek <ja...@redhat.com> PR c++/84448 * parser.c (cp_parser_binary_expression): For no_toplevel_fold_p, if either operand is error_mark_node, set current.lhs to that instead of creating a binary op with error_mark_node operands. * g++.dg/gomp/pr84448.C: New test. --- gcc/cp/parser.c (revision 257820) +++ gcc/cp/parser.c (revision 257821) @@ -9331,12 +9331,18 @@ cp_parser_binary_expression (cp_parser* && lookahead_prec <= current.prec && sp == stack) { - current.lhs - = build_min (current.tree_type, - TREE_CODE_CLASS (current.tree_type) == tcc_comparison - ? boolean_type_node : TREE_TYPE (current.lhs), - current.lhs.get_value (), rhs.get_value ()); - SET_EXPR_LOCATION (current.lhs, combined_loc); + if (current.lhs == error_mark_node || rhs == error_mark_node) + current.lhs = error_mark_node; + else + { + current.lhs + = build_min (current.tree_type, + TREE_CODE_CLASS (current.tree_type) + == tcc_comparison + ? boolean_type_node : TREE_TYPE (current.lhs), + current.lhs.get_value (), rhs.get_value ()); + SET_EXPR_LOCATION (current.lhs, combined_loc); + } } else { --- gcc/testsuite/g++.dg/gomp/pr84448.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr84448.C (revision 257821) @@ -0,0 +1,17 @@ +// PR c++/84448 +// { dg-do compile } + +struct A +{ + operator int () const; + A& operator += (int); + A& operator ++ (); +}; + +void +foo (A a, A b) +{ + #pragma omp for + for (A i = a; i <=; ++i) // { dg-error "expected primary-expression before" } + ; // { dg-error "invalid controlling predicate" "" { target *-*-* } .-1 } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-19 Jakub Jelinek <ja...@redhat.com> PR c++/84444 * builtins.c (builtin_mathfn_code): Don't check if CALL_EXPR_FN (t) is ADDR_EXPR. * g++.dg/cpp1z/launder8.C: New test. --- gcc/builtins.c (revision 257821) +++ gcc/builtins.c (revision 257822) @@ -7836,8 +7836,7 @@ builtin_mathfn_code (const_tree t) const_tree argtype, parmtype; const_call_expr_arg_iterator iter; - if (TREE_CODE (t) != CALL_EXPR - || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR) + if (TREE_CODE (t) != CALL_EXPR) return END_BUILTINS; fndecl = get_callee_fndecl (t); --- gcc/testsuite/g++.dg/cpp1z/launder8.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/launder8.C (revision 257822) @@ -0,0 +1,11 @@ +// PR c++/84444 +// { dg-do compile } +// { dg-options "-O2" } + +struct A {}; + +__UINTPTR_TYPE__ +foo (A *p) +{ + return (__UINTPTR_TYPE__) __builtin_launder (p); +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-20 Jakub Jelinek <ja...@redhat.com> PR c++/84449 * tree.c (bot_manip): If build_cplus_new or break_out_target_exprs returns error_mark_node, return it immediately. (break_out_target_exprs): If cp_walk_tree with bot_manip returns error_mark_node, return error_mark_node. * g++.dg/cpp0x/constexpr-84449.C: New test. --- gcc/cp/tree.c (revision 257838) +++ gcc/cp/tree.c (revision 257839) @@ -2896,6 +2896,8 @@ bot_manip (tree* tp, int* walk_subtrees, { u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1), tf_warning_or_error); + if (u == error_mark_node) + return u; if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1))) AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true; } @@ -2913,6 +2915,8 @@ bot_manip (tree* tp, int* walk_subtrees, (splay_tree_value) TREE_OPERAND (u, 0)); TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1)); + if (TREE_OPERAND (u, 1) == error_mark_node) + return error_mark_node; /* Replace the old expression with the new version. */ *tp = u; @@ -3025,7 +3029,8 @@ break_out_target_exprs (tree t) target_remap = splay_tree_new (splay_tree_compare_pointers, /*splay_tree_delete_key_fn=*/NULL, /*splay_tree_delete_value_fn=*/NULL); - cp_walk_tree (&t, bot_manip, target_remap, NULL); + if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node) + t = error_mark_node; cp_walk_tree (&t, bot_replace, target_remap, NULL); if (!--target_remap_count) --- gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C (revision 257839) @@ -0,0 +1,14 @@ +// PR c++/84449 +// { dg-do compile { target c++11 } } + +struct A +{ + constexpr A (int) {} + ~A () = delete; +}; + +struct B +{ + A a; + constexpr B () : a (0) {} // { dg-error "use of deleted function" } +};
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-20 Jakub Jelinek <ja...@redhat.com> PR c++/84445 * class.c (fixed_type_or_null) <case CALL_EXPR>: Only test TREE_HAS_CONSTRUCTOR if instance is not an internal function call. * g++.dg/cpp1z/launder7.C: New test. --- gcc/cp/class.c (revision 257839) +++ gcc/cp/class.c (revision 257840) @@ -7128,7 +7128,8 @@ fixed_type_or_null (tree instance, int * case CALL_EXPR: /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) + if (CALL_EXPR_FN (instance) + && TREE_HAS_CONSTRUCTOR (instance)) { if (nonnull) *nonnull = 1; --- gcc/testsuite/g++.dg/cpp1z/launder7.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/launder7.C (revision 257840) @@ -0,0 +1,10 @@ +// PR c++/84445 +// { dg-do compile } + +struct A { virtual void foo (); }; + +void +bar (A *p) +{ + __builtin_launder (p)->foo (); +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-22 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/84503 * gcc.dg/pr84503-1.c: New test. * gcc.dg/pr84503-2.c: New test. 2017-11-10 Jakub Jelinek <ja...@redhat.com> PR bootstrap/82916 * gimple-ssa-store-merging.c (pass_store_merging::terminate_all_aliasing_chains): For gimple_store_p stmts also call refs_output_dependent_p. * gcc.dg/pr82916.c: New test. --- gcc/gimple-ssa-store-merging.c (revision 254622) +++ gcc/gimple-ssa-store-merging.c (revision 254623) @@ -812,12 +812,14 @@ pass_store_merging::terminate_all_aliasi { struct store_immediate_info *info; unsigned int i; + tree store_lhs + = gimple_store_p (stmt) ? gimple_get_lhs (stmt) : NULL_TREE; FOR_EACH_VEC_ELT ((*chain_info)->m_store_info, i, info) { - if (ref_maybe_used_by_stmt_p (stmt, - gimple_assign_lhs (info->stmt)) - || stmt_may_clobber_ref_p (stmt, - gimple_assign_lhs (info->stmt))) + tree lhs = gimple_assign_lhs (info->stmt); + if (ref_maybe_used_by_stmt_p (stmt, lhs) + || stmt_may_clobber_ref_p (stmt, lhs) + || (store_lhs && refs_output_dependent_p (store_lhs, lhs))) { if (dump_file && (dump_flags & TDF_DETAILS)) { --- gcc/testsuite/gcc.dg/pr82916.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr82916.c (revision 254623) @@ -0,0 +1,47 @@ +/* PR bootstrap/82916 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-tree-dse" } */ + +struct A { struct A *next; }; +struct C +{ + int *of; + struct C *parent, *prev, *next; + int depth; + int min; + struct C *min_occ; +}; + +__attribute__((noinline, noclone)) struct C * +foo (int *node) +{ + struct A *p = __builtin_malloc (sizeof (struct C)); + if (!p) + return 0; + p->next = 0; + /* Originally placement new. */ + struct C *nw = (struct C *)(void *)p; + nw->of = node; + nw->parent = 0; + nw->prev = 0; + nw->next = 0; + nw->depth = 0; + nw->min_occ = nw; + nw->min = 0; + return nw; +} + +int +main () +{ + int o; + struct C *p = foo (&o); + if (p) + { + if (p->of != &o || p->parent || p->prev || p->next || p->depth + || p->min || p->min_occ != p) + __builtin_abort (); + } + __builtin_free (p); + return 0; +} --- gcc/testsuite/gcc.dg/pr84503-1.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84503-1.c (revision 257891) @@ -0,0 +1,68 @@ +/* PR tree-optimization/84503 */ +/* { dg-do run } */ +/* { dg-options "-O3" } */ + +typedef __SIZE_TYPE__ size_t; +typedef __UINTPTR_TYPE__ uintptr_t; + +struct S { int a; unsigned short b; int c, d, e; long f, g, h; int i, j; }; +static struct S *k; +static size_t l = 0; +int m; + +static int +bar (void) +{ + unsigned i; + int j; + if (k[0].c == 0) + { + ++m; + size_t n = l * 2; + struct S *o; + o = (struct S *) __builtin_realloc (k, sizeof (struct S) * n); + if (!o) + __builtin_exit (0); + k = o; + for (i = l; i < n; i++) + { + void *p = (void *) &k[i]; + int q = 0; + size_t r = sizeof (struct S); + if ((((uintptr_t) p) % __alignof__ (long)) == 0 + && r % sizeof (long) == 0) + { + long __attribute__ ((may_alias)) *s = (long *) p; + long *t = (long *) ((char *) s + r); + while (s < t) + *s++ = 0; + } + else + __builtin_memset (p, q, r); + k[i].c = i + 1; + k[i].a = -1; + } + k[n - 1].c = 0; + k[0].c = l; + l = n; + } + j = k[0].c; + k[0].c = k[j].c; + return j; +} + +int +main () +{ + k = (struct S *) __builtin_malloc (sizeof (struct S)); + if (!k) + __builtin_exit (0); + __builtin_memset (k, '\0', sizeof (struct S)); + k->a = -1; + l = 1; + for (int i = 0; i < 15; ++i) + bar (); + if (m != 4) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.dg/pr84503-2.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84503-2.c (revision 257891) @@ -0,0 +1,5 @@ +/* PR tree-optimization/84503 */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-tree-vectorize -fno-ivopts" } */ + +#include "pr84503-1.c"
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-23 Jakub Jelinek <ja...@redhat.com> * ipa-prop.c (ipa_vr_ggc_hash_traits::hash): Hash p->min and p->max as pointers rather than using iterative_hash_expr. --- gcc/ipa-prop.c (revision 257939) +++ gcc/ipa-prop.c (revision 257940) @@ -111,12 +111,13 @@ struct ipa_vr_ggc_hash_traits : public g typedef value_range *compare_type; static hashval_t hash (const value_range *p) - { - gcc_checking_assert (!p->equiv); - hashval_t t = (hashval_t) p->type; - t = iterative_hash_expr (p->min, t); - return iterative_hash_expr (p->max, t); - } + { + gcc_checking_assert (!p->equiv); + inchash::hash hstate (p->type); + hstate.add_ptr (p->min); + hstate.add_ptr (p->max); + return hstate.end (); + } static bool equal (const value_range *a, const value_range *b) {
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-26 Jakub Jelinek <ja...@redhat.com> PR c++/84556 * g++.dg/gomp/pr84556.C: New test. * g++.dg/vect/pr84556.cc: New test. --- gcc/testsuite/g++.dg/vect/pr84556.cc (nonexistent) +++ gcc/testsuite/g++.dg/vect/pr84556.cc (revision 257986) @@ -0,0 +1,21 @@ +// PR c++/84556 +// { dg-do run { target c++11 } } +// { dg-options "-O2 -fopenmp-simd" } +// { dg-additional-options "-mavx" { target avx_runtime } } + +int +main () +{ + int y[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + auto x = [&y] () + { + #pragma omp simd + for (int i = 0; i < 8; ++i) + y[i]++; + }; + x (); + x (); + for (int i = 0; i < 8; ++i) + if (y[i] != i + 3) + __builtin_abort (); +} --- gcc/testsuite/g++.dg/gomp/pr84556.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr84556.C (revision 257986) @@ -0,0 +1,14 @@ +// PR c++/84556 +// { dg-do compile } +// { dg-options "-std=c++17 -fopenmp-simd" } + +void +foo () +{ + auto x = [] () + { + #pragma omp simd + for (int i = 0; i < 8; ++i) + ; + }; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-26 Jakub Jelinek <ja...@redhat.com> PR c++/84557 * parser.c (cp_parser_omp_var_list_no_open): Only call cp_parser_lookup_name_simple on names satisfying identifier_p. (cp_parser_oacc_routine): Likewise. * g++.dg/gomp/pr84557.C: New test. --- gcc/cp/parser.c (revision 258010) +++ gcc/cp/parser.c (revision 258011) @@ -31342,7 +31342,10 @@ cp_parser_omp_var_list_no_open (cp_parse if (name == error_mark_node) goto skip_comma; - decl = cp_parser_lookup_name_simple (parser, name, token->location); + if (identifier_p (name)) + decl = cp_parser_lookup_name_simple (parser, name, token->location); + else + decl = name; if (decl == error_mark_node) cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, token->location); @@ -37846,7 +37849,9 @@ cp_parser_oacc_routine (cp_parser *parse /*template_p=*/NULL, /*declarator_p=*/false, /*optional_p=*/false); - tree decl = cp_parser_lookup_name_simple (parser, name, name_loc); + tree decl = (identifier_p (name) + ? cp_parser_lookup_name_simple (parser, name, name_loc) + : name); if (name != error_mark_node && decl == error_mark_node) cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, name_loc); --- gcc/testsuite/g++.dg/gomp/pr84557.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr84557.C (revision 258011) @@ -0,0 +1,14 @@ +// PR c++/84557 +// { dg-do compile } + +template<int> struct A {}; +template<int> struct B {}; + +void +foo () +{ + #pragma omp parallel firstprivate (A) // { dg-error "is not a variable in clause" } + ; + #pragma omp parallel firstprivate (B<0>) // { dg-error "is not a variable in clause" } + ; +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-02-26 Jakub Jelinek <ja...@redhat.com> PR c++/84558 * constexpr.c (cxx_eval_vec_init_1): For reuse, treat NULL eltinit like a valid constant initializer. Formatting fixes. * g++.dg/cpp1y/pr84558.C: New test. --- gcc/cp/constexpr.c (revision 258013) +++ gcc/cp/constexpr.c (revision 258014) @@ -2959,9 +2959,8 @@ cxx_eval_vec_init_1 (const constexpr_ctx if (!lvalue_p (init)) eltinit = move (eltinit); eltinit = force_rvalue (eltinit, tf_warning_or_error); - eltinit = (cxx_eval_constant_expression - (&new_ctx, eltinit, lval, - non_constant_p, overflow_p)); + eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval, + non_constant_p, overflow_p); } if (*non_constant_p && !ctx->quiet) break; @@ -2974,12 +2973,13 @@ cxx_eval_vec_init_1 (const constexpr_ctx else CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit); /* Reuse the result of cxx_eval_constant_expression call - from the first iteration to all others if it is a constant - initializer that doesn't require relocations. */ + from the first iteration to all others if it is a constant + initializer that doesn't require relocations. */ if (reuse && max > 1 - && (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) - == null_pointer_node)) + && (eltinit == NULL_TREE + || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) + == null_pointer_node))) { if (new_ctx.ctor != ctx->ctor) eltinit = new_ctx.ctor; --- gcc/testsuite/g++.dg/cpp1y/pr84558.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1y/pr84558.C (revision 258014) @@ -0,0 +1,6 @@ +// PR c++/84558 +// { dg-do compile { target c++14 } } + +struct A { static int i; constexpr A () { i = 0; } }; +struct B { A a[2][3][4]; }; +B b;
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-02 Jakub Jelinek <ja...@redhat.com> PR sanitizer/70875 * gcc.dg/ubsan/bounds-3.c: Add -fno-sanitize-recover=bounds to dg-options and dg-shouldfail "ubsan" directive. --- gcc/testsuite/gcc.dg/ubsan/bounds-3.c (revision 258116) +++ gcc/testsuite/gcc.dg/ubsan/bounds-3.c (revision 258117) @@ -1,6 +1,7 @@ /* PR sanitizer/70875 */ /* { dg-do run } */ -/* { dg-options "-fsanitize=bounds" } */ +/* { dg-options "-fsanitize=bounds -fno-sanitize-recover=bounds" } */ +/* { dg-shouldfail "ubsan" } */ int foo (int n, int k)
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-02 Jakub Jelinek <ja...@redhat.com> PR inline-asm/84625 * config/i386/i386.c (ix86_print_operand): Use conditional output_operand_lossage instead of gcc_assert if CONST_VECTOR is not zero vector. * gcc.target/i386/pr84625.c: New test. --- gcc/config/i386/i386.c (revision 258124) +++ gcc/config/i386/i386.c (revision 258125) @@ -18743,7 +18743,8 @@ ix86_print_operand (FILE *file, rtx x, i since we can in fact encode that into an immediate. */ if (GET_CODE (x) == CONST_VECTOR) { - gcc_assert (x == CONST0_RTX (GET_MODE (x))); + if (x != CONST0_RTX (GET_MODE (x))) + output_operand_lossage ("invalid vector immediate"); x = const0_rtx; } --- gcc/testsuite/gcc.target/i386/pr84625.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr84625.c (revision 258125) @@ -0,0 +1,12 @@ +/* PR inline-asm/84625 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2" } */ + +typedef int V __attribute__((vector_size (16))); + +void +foo (void) +{ + asm volatile ("# %0" : : "X" ((V) { 1, 2, 3, 4 })); // { dg-error "invalid vector immediate" } + asm volatile ("# %0" : : "" ((V) { 2, 3, 4, 5 })); // { dg-error "invalid vector immediate" } +}
2018-03-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2018-03-02 Jakub Jelinek <ja...@redhat.com> Richard Biener <rguent...@suse.de> PR ipa/84628 * expr.c (expand_expr_real_1) <case CALL_EXPR>: Don't emit diagnostics for error or warning attributes if CALL_FROM_THUNK_P is set. Formatting fixes. * gcc.dg/pr84628.c: New test. --- gcc/expr.c (revision 258139) +++ gcc/expr.c (revision 258140) @@ -10963,18 +10963,30 @@ expand_expr_real_1 (tree exp, rtx target tree fndecl = get_callee_fndecl (exp), attr; if (fndecl + /* Don't diagnose the error attribute in thunks, those are + artificially created. */ + && !CALL_FROM_THUNK_P (exp) && (attr = lookup_attribute ("error", DECL_ATTRIBUTES (fndecl))) != NULL) - error ("%Kcall to %qs declared with attribute error: %s", - exp, identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 1)), - TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + { + const char *ident = lang_hooks.decl_printable_name (fndecl, 1); + error ("%Kcall to %qs declared with attribute error: %s", exp, + identifier_to_locale (ident), + TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + } if (fndecl + /* Don't diagnose the warning attribute in thunks, those are + artificially created. */ + && !CALL_FROM_THUNK_P (exp) && (attr = lookup_attribute ("warning", DECL_ATTRIBUTES (fndecl))) != NULL) - warning_at (tree_nonartificial_location (exp), - 0, "%Kcall to %qs declared with attribute warning: %s", - exp, identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 1)), - TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + { + const char *ident = lang_hooks.decl_printable_name (fndecl, 1); + warning_at (tree_nonartificial_location (exp), 0, + "%Kcall to %qs declared with attribute warning: %s", + exp, identifier_to_locale (ident), + TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + } /* Check for a built-in function. */ if (fndecl && DECL_BUILT_IN (fndecl)) --- gcc/testsuite/gcc.dg/pr84628.c (nonexistent) +++ gcc/testsuite/gcc.dg/pr84628.c (revision 258140) @@ -0,0 +1,8 @@ +/* PR ipa/84628 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f0 (void); +__attribute__((error ("err"))) void f1 (void) { f0 (); f0 (); } +__attribute__((error ("err"))) void f2 (void) { f0 (); f0 (); } +/* { dg-bogus "declared with attribute error" "" { target *-*-* } 0 } */