Hi! I've bootstrapped/regtested following patches on x86_64-linux and i686-linux on gcc-6-branch and committed them to 6.x.
Jakub
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-01-17 Kito Cheng <kito.ch...@gmail.com> Kuan-Lin Chen <kuanlinche...@gmail.com> PR target/79079 * internal-fn.c (expand_mul_overflow): Use convert_modes instead of gen_lowpart. --- gcc/internal-fn.c (revision 244538) +++ gcc/internal-fn.c (revision 244539) @@ -1483,8 +1483,8 @@ expand_mul_overflow (location_t loc, tre res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL); rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec, NULL_RTX, uns); - hipart = gen_lowpart (mode, hipart); - res = gen_lowpart (mode, res); + hipart = convert_modes (mode, wmode, hipart, uns); + res = convert_modes (mode, wmode, res, uns); if (uns) /* For the unsigned multiplication, there was overflow if HIPART is non-zero. */ @@ -1517,16 +1517,16 @@ expand_mul_overflow (location_t loc, tre unsigned int hprec = GET_MODE_PRECISION (hmode); rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec, NULL_RTX, uns); - hipart0 = gen_lowpart (hmode, hipart0); - rtx lopart0 = gen_lowpart (hmode, op0); + hipart0 = convert_modes (hmode, mode, hipart0, uns); + rtx lopart0 = convert_modes (hmode, mode, op0, uns); rtx signbit0 = const0_rtx; if (!uns) signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1, NULL_RTX, 0); rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec, NULL_RTX, uns); - hipart1 = gen_lowpart (hmode, hipart1); - rtx lopart1 = gen_lowpart (hmode, op1); + hipart1 = convert_modes (hmode, mode, hipart1, uns); + rtx lopart1 = convert_modes (hmode, mode, op1, uns); rtx signbit1 = const0_rtx; if (!uns) signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1, @@ -1717,11 +1717,12 @@ expand_mul_overflow (location_t loc, tre if (loxhi >> (bitsize / 2) == 0 (if uns). */ rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec, NULL_RTX, 0); - hipartloxhi = gen_lowpart (hmode, hipartloxhi); + hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0); rtx signbitloxhi = const0_rtx; if (!uns) signbitloxhi = expand_shift (RSHIFT_EXPR, hmode, - gen_lowpart (hmode, loxhi), + convert_modes (hmode, mode, + loxhi, 0), hprec - 1, NULL_RTX, 0); do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode, @@ -1731,7 +1732,8 @@ expand_mul_overflow (location_t loc, tre /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1; */ rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec, NULL_RTX, 1); - tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1); + tem = convert_modes (mode, hmode, + convert_modes (hmode, mode, lo0xlo1, 1), 1); tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res, 1, OPTAB_DIRECT);
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-01-31 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/79267 * value-prof.c (gimple_ic): Only drop lhs for noreturn calls if should_remove_lhs_p is true. * g++.dg/opt/pr79267.C: New test. --- gcc/value-prof.c (revision 245052) +++ gcc/value-prof.c (revision 245053) @@ -1376,7 +1376,13 @@ gimple_ic (gcall *icall_stmt, struct cgr gimple_call_set_fndecl (dcall_stmt, direct_call->decl); dflags = flags_from_decl_or_type (direct_call->decl); if ((dflags & ECF_NORETURN) != 0) - gimple_call_set_lhs (dcall_stmt, NULL_TREE); + { + tree lhs = gimple_call_lhs (dcall_stmt); + if (lhs + && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST + && !TREE_ADDRESSABLE (TREE_TYPE (lhs))) + gimple_call_set_lhs (dcall_stmt, NULL_TREE); + } gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); /* Fix CFG. */ --- gcc/testsuite/g++.dg/opt/pr79267.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr79267.C (revision 245053) @@ -0,0 +1,69 @@ +// PR tree-optimization/79267 +// { dg-do compile } +// { dg-options "-O3" } + +struct A { A (int); }; +struct B +{ + virtual void av () = 0; + void aw (); + void h () { av (); aw (); } +}; +template <class T> struct G : B +{ + T ba; + G (int, T) : ba (0) {} + void av () { ba (0); } +}; +struct I +{ + B *bc; + template <class j, class T> I (j, T) try { G<T> (0, 0); } catch (...) {} + ~I () { bc->h (); } +}; +template <class M> struct C { typedef M *i; }; +template <class M> struct J +{ + J (); + template <class O, class T> J (O, T p2) : be (0, p2) {} + typename C<M>::i operator-> (); + I be; +}; +struct H : A { H () : A (0) {} }; +struct D { J<int> d; void q (); }; +template <typename = int> class bs; +int z; + +void +foo (int p1, int *, int) +{ + if (p1 == 0) + throw H (); +} + +D bar (); +template <typename T> struct L +{ + struct K { K (int); void operator() (int *) { bar ().q (); } }; + static J<T> bp () { bq (0); } + template <typename br> static void bq (br) { J<T> (0, K (0)); } +}; +struct F +{ + virtual J<int> x (int) { foo (0, 0, 0); J<bs<> > (L<bs<> >::bp ()); } +}; + +void +baz () +{ + if (z) + { + J<F> d, e; + d->x (0); + e->x (0); + } + J<F> v, i, j; + v->x (0); + i->x (0); + j->x (0); +}
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-02 Jakub Jelinek <ja...@redhat.com> PR target/79197 * config/rs6000/rs6000.md (*fixuns_trunc<mode>di2_fctiduz): Rename to ... (fixuns_trunc<mode>di2): ... this, remove previous expander. Put all conditions on a single line. * gcc.target/powerpc/pr79197.c: New test. * gcc.c-torture/compile/pr79197.c: New test. --- gcc/config/rs6000/rs6000.md (revision 245119) +++ gcc/config/rs6000/rs6000.md (revision 245120) @@ -5429,17 +5429,10 @@ (define_insn_and_split "fixuns_trunc<mod [(set_attr "length" "12") (set_attr "type" "fp")]) -(define_expand "fixuns_trunc<mode>di2" - [(set (match_operand:DI 0 "register_operand" "") - (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))" - "") - -(define_insn "*fixuns_trunc<mode>di2_fctiduz" +(define_insn "fixuns_trunc<mode>di2" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS - && TARGET_FCTIDUZ" + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ" "@ fctiduz %0,%1 xscvdpuxds %x0,%x1" --- gcc/testsuite/gcc.target/powerpc/pr79197.c (nonexistent) +++ gcc/testsuite/gcc.target/powerpc/pr79197.c (revision 245120) @@ -0,0 +1,11 @@ +/* PR target/79197 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mno-popcntd" } */ + +unsigned a; + +void +foo (void) +{ + a = *(double *) (__UINTPTR_TYPE__) 0x400000; +} --- gcc/testsuite/gcc.c-torture/compile/pr79197.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr79197.c (revision 245120) @@ -0,0 +1,10 @@ +/* PR target/79197 */ + +unsigned long b; + +unsigned long +foo (float *a, float *x) +{ + __builtin_memcpy (a, x, sizeof (float)); + return *a; +}
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-04 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/79338 * tree-parloops.c (gather_scalar_reductions): Don't call vect_analyze_loop_form for loop->inner before destroying loop's loop_vinfo. --- gcc/tree-parloops.c (revision 245182) +++ gcc/tree-parloops.c (revision 245183) @@ -2513,8 +2513,8 @@ gather_scalar_reductions (loop_p loop, r { gphi_iterator gsi; loop_vec_info simple_loop_info; - loop_vec_info simple_inner_loop_info = NULL; - bool allow_double_reduc = true; + auto_vec<gphi *, 4> double_reduc_phis; + auto_vec<gimple *, 4> double_reduc_stmts; if (!stmt_vec_info_vec.exists ()) init_stmt_vec_info_vec (); @@ -2544,43 +2544,55 @@ gather_scalar_reductions (loop_p loop, r if (double_reduc) { - if (!allow_double_reduc - || loop->inner->inner != NULL) + if (loop->inner->inner != NULL) continue; - if (!simple_inner_loop_info) - { - simple_inner_loop_info = vect_analyze_loop_form (loop->inner); - if (!simple_inner_loop_info) - { - allow_double_reduc = false; - continue; - } - } - - use_operand_p use_p; - gimple *inner_stmt; - bool single_use_p = single_imm_use (res, &use_p, &inner_stmt); - gcc_assert (single_use_p); - if (gimple_code (inner_stmt) != GIMPLE_PHI) - continue; - gphi *inner_phi = as_a <gphi *> (inner_stmt); - if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi), - &iv, true)) - continue; - - gimple *inner_reduc_stmt - = vect_force_simple_reduction (simple_inner_loop_info, inner_phi, - true, &double_reduc, true); - gcc_assert (!double_reduc); - if (inner_reduc_stmt == NULL) - continue; + double_reduc_phis.safe_push (phi); + double_reduc_stmts.safe_push (reduc_stmt); + continue; } build_new_reduction (reduction_list, reduc_stmt, phi); } destroy_loop_vec_info (simple_loop_info, true); - destroy_loop_vec_info (simple_inner_loop_info, true); + + if (!double_reduc_phis.is_empty ()) + { + simple_loop_info = vect_analyze_loop_form (loop->inner); + if (simple_loop_info) + { + gphi *phi; + unsigned int i; + + FOR_EACH_VEC_ELT (double_reduc_phis, i, phi) + { + affine_iv iv; + tree res = PHI_RESULT (phi); + bool double_reduc; + + use_operand_p use_p; + gimple *inner_stmt; + bool single_use_p = single_imm_use (res, &use_p, &inner_stmt); + gcc_assert (single_use_p); + if (gimple_code (inner_stmt) != GIMPLE_PHI) + continue; + gphi *inner_phi = as_a <gphi *> (inner_stmt); + if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi), + &iv, true)) + continue; + + gimple *inner_reduc_stmt + = vect_force_simple_reduction (simple_loop_info, inner_phi, + true, &double_reduc, true); + gcc_assert (!double_reduc); + if (inner_reduc_stmt == NULL) + continue; + + build_new_reduction (reduction_list, double_reduc_stmts[i], phi); + } + destroy_loop_vec_info (simple_loop_info, true); + } + } gather_done: /* Release the claim on gimple_uid. */
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-06 Jakub Jelinek <ja...@redhat.com> PR c++/79377 * tree.c (build_min_non_dep_op_overload): For POST{INC,DEC}REMENT_EXPR allow one fewer than expected arguments if flag_permissive. * g++.dg/lookup/pr79377.C: New test. --- gcc/cp/tree.c (revision 245218) +++ gcc/cp/tree.c (revision 245219) @@ -2938,8 +2938,10 @@ build_min_non_dep_op_overload (enum tree nargs = call_expr_nargs (non_dep); expected_nargs = cp_tree_code_length (op); - if (op == POSTINCREMENT_EXPR - || op == POSTDECREMENT_EXPR) + if ((op == POSTINCREMENT_EXPR + || op == POSTDECREMENT_EXPR) + /* With -fpermissive non_dep could be operator++(). */ + && (!flag_permissive || nargs != expected_nargs)) expected_nargs += 1; gcc_assert (nargs == expected_nargs); --- gcc/testsuite/g++.dg/lookup/pr79377.C (nonexistent) +++ gcc/testsuite/g++.dg/lookup/pr79377.C (revision 245219) @@ -0,0 +1,36 @@ +// PR c++/79377 +// { dg-do run } +// { dg-options "-fpermissive" } + +struct A +{ + A () : a (0) {} + A& operator++ () { ++a; ++c; return *this; } + int a; + static int c; +}; + +int A::c = 0; + +template <typename> +void +foo (A& a) +{ + a++; // { dg-warning "trying prefix operator instead" } + if (A::c != 3 || a.a != 3) __builtin_abort (); + ++a; + if (A::c != 4 || a.a != 4) __builtin_abort (); +} + +int +main () +{ + A a; + if (A::c != 0 || a.a != 0) __builtin_abort (); + ++a; + if (A::c != 1 || a.a != 1) __builtin_abort (); + a++; // { dg-warning "trying prefix operator instead" } + if (A::c != 2 || a.a != 2) __builtin_abort (); + foo<int> (a); + if (A::c != 4 || a.a != 4) __builtin_abort (); +}
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-07 Jakub Jelinek <ja...@redhat.com> Richard Biener <rguent...@suse.de> PR middle-end/79399 * ira-int.h (struct target_ira_int): Change x_max_struct_costs_size type from int to size_t. * ira-costs.c (struct_costs_size): Change type from int to size_t. --- gcc/ira-int.h (revision 245255) +++ gcc/ira-int.h (revision 245256) @@ -782,7 +782,7 @@ struct target_ira_int { /* Initialized once. It is a maximal possible size of the allocated struct costs. */ - int x_max_struct_costs_size; + size_t x_max_struct_costs_size; /* Allocated and initialized once, and used to initialize cost values for each insn. */ --- gcc/ira-costs.c (revision 245255) +++ gcc/ira-costs.c (revision 245256) @@ -74,7 +74,7 @@ static struct costs *costs; static struct costs *total_allocno_costs; /* It is the current size of struct costs. */ -static int struct_costs_size; +static size_t struct_costs_size; /* Return pointer to structure containing costs of allocno or pseudo with given NUM in array ARR. */
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-09 Jakub Jelinek <ja...@redhat.com> PR c/79431 * gimplify.c (gimplify_adjust_omp_clauses): Ignore "omp declare target link" attribute unless is_global_var. * omp-low.c (find_link_var_op): Likewise. * c-parser.c (c_parser_omp_declare_target): Don't invoke symtab_node::get on automatic variables. * parser.c (cp_parser_oacc_declare): Formatting fix. (cp_parser_omp_declare_target): Don't invoke symtab_node::get on automatic variables. * c-c++-common/gomp/pr79431.c: New test. --- gcc/gimplify.c (revision 245301) +++ gcc/gimplify.c (revision 245302) @@ -8938,8 +8938,9 @@ gimplify_adjust_omp_clauses (gimple_seq if ((ctx->region_type & ORT_TARGET) != 0 && !(n->value & GOVD_SEEN) && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0 - && !lookup_attribute ("omp declare target link", - DECL_ATTRIBUTES (decl))) + && (!is_global_var (decl) + || !lookup_attribute ("omp declare target link", + DECL_ATTRIBUTES (decl)))) { remove = true; /* For struct element mapping, if struct is never referenced --- gcc/omp-low.c (revision 245301) +++ gcc/omp-low.c (revision 245302) @@ -19890,7 +19890,9 @@ find_link_var_op (tree *tp, int *walk_su { tree t = *tp; - if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t) + if (TREE_CODE (t) == VAR_DECL + && DECL_HAS_VALUE_EXPR_P (t) + && is_global_var (t) && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t))) { *walk_subtrees = 0; --- gcc/c/c-parser.c (revision 245301) +++ gcc/c/c-parser.c (revision 245302) @@ -16849,8 +16849,11 @@ c_parser_omp_declare_target (c_parser *p } if (!at1) { - symtab_node *node = symtab_node::get (t); DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); + if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t)) + continue; + + symtab_node *node = symtab_node::get (t); if (node != NULL) { node->offloadable = 1; --- gcc/cp/parser.c (revision 245301) +++ gcc/cp/parser.c (revision 245302) @@ -36230,7 +36230,7 @@ cp_parser_oacc_declare (cp_parser *parse id = get_identifier ("omp declare target"); DECL_ATTRIBUTES (decl) - = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); + = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); if (global_bindings_p ()) { symtab_node *node = symtab_node::get (decl); @@ -36770,8 +36770,11 @@ cp_parser_omp_declare_target (cp_parser } if (!at1) { - symtab_node *node = symtab_node::get (t); DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); + if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t)) + continue; + + symtab_node *node = symtab_node::get (t); if (node != NULL) { node->offloadable = 1; --- gcc/testsuite/c-c++-common/gomp/pr79431.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr79431.c (revision 245302) @@ -0,0 +1,8 @@ +/* PR c/79431 */ + +void +foo (void) +{ + int a; + #pragma omp declare target (a) +}
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-09 Jakub Jelinek <ja...@redhat.com> PR c++/79429 * parser.c (cp_parser_omp_ordered): Don't check for non-pragma_stmt non-pragma_compound context here. (cp_parser_omp_target): Likewise. (cp_parser_pragma): Don't call push_omp_privatization_clauses and parsing for ordered and target omp pragmas in non-pragma_stmt non-pragma_compound contexts. * c-c++-common/gomp/pr79429.c: New test. * g++.dg/gomp/pr79429.C: New test. --- gcc/cp/parser.c (revision 245302) +++ gcc/cp/parser.c (revision 245303) @@ -34934,13 +34934,6 @@ cp_parser_omp_ordered (cp_parser *parser { location_t loc = pragma_tok->location; - if (context != pragma_stmt && context != pragma_compound) - { - cp_parser_error (parser, "expected declaration specifiers"); - cp_parser_skip_to_pragma_eol (parser, pragma_tok); - return false; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { tree id = cp_lexer_peek_token (parser->lexer)->u.value; @@ -35846,13 +35839,6 @@ cp_parser_omp_target (cp_parser *parser, { tree *pc = NULL, stmt; - if (context != pragma_stmt && context != pragma_compound) - { - cp_parser_error (parser, "expected declaration specifiers"); - cp_parser_skip_to_pragma_eol (parser, pragma_tok); - return false; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { tree id = cp_lexer_peek_token (parser->lexer)->u.value; @@ -38283,12 +38269,16 @@ cp_parser_pragma (cp_parser *parser, enu return true; case PRAGMA_OMP_ORDERED: + if (context != pragma_stmt && context != pragma_compound) + goto bad_stmt; stmt = push_omp_privatization_clauses (false); ret = cp_parser_omp_ordered (parser, pragma_tok, context, if_p); pop_omp_privatization_clauses (stmt); return ret; case PRAGMA_OMP_TARGET: + if (context != pragma_stmt && context != pragma_compound) + goto bad_stmt; stmt = push_omp_privatization_clauses (false); ret = cp_parser_omp_target (parser, pragma_tok, context, if_p); pop_omp_privatization_clauses (stmt); --- gcc/testsuite/g++.dg/gomp/pr79429.C (nonexistent) +++ gcc/testsuite/g++.dg/gomp/pr79429.C (revision 245303) @@ -0,0 +1,3 @@ +// PR c++/79429 + +#pragma omp ordered // { dg-error "expected declaration specifiers" } --- gcc/testsuite/c-c++-common/gomp/pr79429.c (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr79429.c (revision 245303) @@ -0,0 +1,3 @@ +/* PR c++/79429 */ + +#pragma omp target /* { dg-error "expected declaration specifiers" } */
2017-02-15 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-02-10 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/79411 * tree-ssa-reassoc.c (is_reassociable_op): Return false if stmt operands are SSA_NAMEs used in abnormal phis. (can_reassociate_p): Return false if op is SSA_NAME used in abnormal phis. * gcc.c-torture/compile/pr79411.c: New test. --- gcc/tree-ssa-reassoc.c (revision 245323) +++ gcc/tree-ssa-reassoc.c (revision 245324) @@ -605,7 +605,18 @@ is_reassociable_op (gimple *stmt, enum t if (is_gimple_assign (stmt) && gimple_assign_rhs_code (stmt) == code && has_single_use (gimple_assign_lhs (stmt))) - return true; + { + tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs1 (stmt); + if (TREE_CODE (rhs1) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)) + return false; + if (rhs2 + && TREE_CODE (rhs2) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)) + return false; + return true; + } return false; } @@ -4989,6 +5000,8 @@ static bool can_reassociate_p (tree op) { tree type = TREE_TYPE (op); + if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op)) + return false; if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) || NON_SAT_FIXED_POINT_TYPE_P (type) || (flag_associative_math && FLOAT_TYPE_P (type))) --- gcc/testsuite/gcc.c-torture/compile/pr79411.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr79411.c (revision 245324) @@ -0,0 +1,22 @@ +/* PR tree-optimization/79411 */ + +typedef struct __jmp_buf_tag { char buf[1024]; } jmp_buf[1]; +extern int setjmp (jmp_buf); +extern int bar (unsigned int *); +extern jmp_buf *baz (void); +struct C { int c1; unsigned int c2, c3, c4; }; + +void +foo (struct C *x, const int *y, unsigned int *z, unsigned int e, unsigned int g) +{ + unsigned int d = 0; + unsigned long f; + setjmp (*baz ()); + f = 1 + d; + if ((x->c1 || x->c2) && g && (!e || d >= 8)) + d = 16; + else + d = 8; + if ((!x->c3 && !x->c4 || *y == 0) && !e && bar (z)) + *z = 1 + f; +}