diff options
author | Thomas Schwinge <tschwinge@baylibre.com> | 2024-03-11 00:47:49 +0100 |
---|---|---|
committer | Thomas Schwinge <tschwinge@baylibre.com> | 2024-03-11 00:47:49 +0100 |
commit | 7f7da6c240f2e0284ff201975844673f2ef070c7 (patch) | |
tree | 612ae67f3bf3a7f2ada0b56bbac0ba4a8ef4783d /gcc | |
parent | a1bd74ba1df9efa557d6b4d873f39c36d59ed72c (diff) | |
parent | b59e9de990a17bfd5fa7252b76339c35bff7f2e8 (diff) | |
download | gcc-7f7da6c240f2e0284ff201975844673f2ef070c7.zip gcc-7f7da6c240f2e0284ff201975844673f2ef070c7.tar.gz gcc-7f7da6c240f2e0284ff201975844673f2ef070c7.tar.bz2 |
Merge commit 'af91934c2f6b8efc67d625c99068b4761ae5edd0^' into HEAD
Diffstat (limited to 'gcc')
246 files changed, 4962 insertions, 893 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1797b17..40c3674 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,233 @@ +2023-09-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-v.cc (shuffle_generic_patterns): Expand + fixed-vlmax/vls vector permutation. + +2023-09-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv-v.cc (shuffle_compress_patterns): Avoid unnecessary slideup. + +2023-09-10 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111331 + * match.pd (`(a CMP CST1) ? max<a,CST2> : a`): + Fix the LE/GE comparison to the correct value. + * tree-ssa-phiopt.cc (minmax_replacement): + Fix the LE/GE comparison for the + `(a CMP CST1) ? max<a,CST2> : a` optimization. + +2023-09-10 Iain Sandoe <iain@sandoe.co.uk> + + * config/darwin.cc (darwin_function_section): Place unlikely + executed global init code into the standard cold section. + +2023-09-10 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/111311 + * config/riscv/riscv-vsetvl.cc (pass_vsetvl::vsetvl_fusion): Add TDF_DETAILS. + (pass_vsetvl::pre_vsetvl): Ditto. + (pass_vsetvl::init): Ditto. + (pass_vsetvl::lazy_vsetvl): Ditto. + +2023-09-09 Lulu Cheng <chenglulu@loongson.cn> + + * config/loongarch/loongarch.md (mulsidi3_64bit): + Field unsigned extension support. + (<u>muldi3_highpart): Modify template name. + (<u>mulsi3_highpart): Likewise. + (<u>mulsidi3_64bit): Field unsigned extension support. + (<su>muldi3_highpart): Modify muldi3_highpart to + smuldi3_highpart. + (<su>mulsi3_highpart): Modify mulsi3_highpart to + smulsi3_highpart. + +2023-09-09 Xi Ruoyao <xry111@xry111.site> + + * config/loongarch/loongarch.cc (loongarch_block_move_straight): + Check precondition (delta must be a power of 2) and use + popcount_hwi instead of a homebrew loop. + +2023-09-09 Xi Ruoyao <xry111@xry111.site> + + * config/loongarch/loongarch.h (LARCH_MAX_MOVE_PER_INSN): + Define to the maximum amount of bytes able to be loaded or + stored with one machine instruction. + * config/loongarch/loongarch.cc (loongarch_mode_for_move_size): + New static function. + (loongarch_block_move_straight): Call + loongarch_mode_for_move_size for machine_mode to be moved. + (loongarch_expand_block_move): Use LARCH_MAX_MOVE_PER_INSN + instead of UNITS_PER_WORD. + +2023-09-09 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/vector-iterators.md: Fix floating-point operations predicate. + +2023-09-09 Lehua Ding <lehua.ding@rivai.ai> + + * fold-const.cc (can_min_p): New function. + (poly_int_binop): Try fold MIN_EXPR. + +2023-09-08 Aldy Hernandez <aldyh@redhat.com> + + * range-op-float.cc (foperator_ltgt::fold_range): Do not special + case VREL_EQ nor call frelop_early_resolve. + +2023-09-08 Christoph Müllner <christoph.muellner@vrull.eu> + + * config/riscv/thead.md (*extend<SHORT:mode><SUPERQI:mode>2_th_ext): + Remove broken INSN. + (*extendhi<SUPERQI:mode>2_th_ext): New INSN. + (*extendqi<SUPERQI:mode>2_th_ext): New INSN. + +2023-09-08 Christoph Müllner <christoph.muellner@vrull.eu> + + * config/riscv/thead.md: Use more appropriate mode attributes + for extensions. + +2023-09-08 Guo Jie <guojie@loongson.cn> + + * common/config/loongarch/loongarch-common.cc: + (default_options loongarch_option_optimization_table): + Default to -fsched-pressure. + +2023-09-08 Yang Yujie <yangyujie@loongson.cn> + + * config.gcc: remove non-POSIX syntax "<<<". + +2023-09-08 Christoph Müllner <christoph.muellner@vrull.eu> + + * config/riscv/bitmanip.md (*extend<SHORT:mode><SUPERQI:mode>2_zbb): + Rename postfix to _bitmanip. + (*extend<SHORT:mode><SUPERQI:mode>2_bitmanip): Renamed pattern. + (*zero_extendhi<GPR:mode>2_zbb): Remove duplicated pattern. + +2023-09-08 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv.cc (riscv_pass_in_vector_p): Only allow RVV type. + +2023-09-08 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/riscv.cc (riscv_hard_regno_nregs): Fix bug. + +2023-09-07 liuhongt <hongtao.liu@intel.com> + + * config/i386/sse.md + (<avx512>_vpermt2var<mode>3<sd_maskz_name>): New define_insn. + (VHFBF_AVX512VL): New mode iterator. + (VI2HFBF_AVX512VL): New mode iterator. + +2023-09-07 Aldy Hernandez <aldyh@redhat.com> + + * value-range.h (contains_zero_p): Return false for undefined ranges. + * range-op-float.cc (operator_gt::op1_op2_relation): Adjust for + contains_zero_p change above. + (operator_ge::op1_op2_relation): Same. + (operator_equal::op1_op2_relation): Same. + (operator_not_equal::op1_op2_relation): Same. + (operator_lt::op1_op2_relation): Same. + (operator_le::op1_op2_relation): Same. + (operator_ge::op1_op2_relation): Same. + * range-op.cc (operator_equal::op1_op2_relation): Same. + (operator_not_equal::op1_op2_relation): Same. + (operator_lt::op1_op2_relation): Same. + (operator_le::op1_op2_relation): Same. + (operator_cast::op1_range): Same. + (set_nonzero_range_from_mask): Same. + (operator_bitwise_xor::op1_range): Same. + (operator_addr_expr::fold_range): Same. + (operator_addr_expr::op1_range): Same. + +2023-09-07 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/110875 + * gimple-range.cc (gimple_ranger::prefill_name): Only invoke + cache-prefilling routine when the ssa-name has no global value. + +2023-09-07 Vladimir N. Makarov <vmakarov@redhat.com> + + PR target/111225 + * lra-constraints.cc (goal_reuse_alt_p): New global flag. + (process_alt_operands): Set up the flag. Clear flag for chosen + alternative with special memory constraints. + (process_alt_operands): Set up used insn alternative depending on the flag. + +2023-09-07 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + * config/riscv/autovec-vls.md: Add VLS mask modes mov patterns. + * config/riscv/riscv.md: Ditto. + * config/riscv/vector-iterators.md: Ditto. + * config/riscv/vector.md: Ditto. + +2023-09-07 David Malcolm <dmalcolm@redhat.com> + + * diagnostic-core.h (error_meta): New decl. + * diagnostic.cc (error_meta): New. + +2023-09-07 Jakub Jelinek <jakub@redhat.com> + + PR c/102989 + * expr.cc (expand_expr_real_1): Don't call targetm.c.bitint_type_info + inside gcc_assert, as later code relies on it filling info variable. + * gimple-fold.cc (clear_padding_bitint_needs_padding_p, + clear_padding_type): Likewise. + * varasm.cc (output_constant): Likewise. + * fold-const.cc (native_encode_int, native_interpret_int): Likewise. + * stor-layout.cc (finish_bitfield_representative, layout_type): + Likewise. + * gimple-lower-bitint.cc (bitint_precision_kind): Likewise. + +2023-09-07 Xi Ruoyao <xry111@xry111.site> + + PR target/111252 + * config/loongarch/loongarch-protos.h + (loongarch_pre_reload_split): Declare new function. + (loongarch_use_bstrins_for_ior_with_mask): Likewise. + * config/loongarch/loongarch.cc + (loongarch_pre_reload_split): Implement. + (loongarch_use_bstrins_for_ior_with_mask): Likewise. + * config/loongarch/predicates.md (ins_zero_bitmask_operand): + New predicate. + * config/loongarch/loongarch.md (bstrins_<mode>_for_mask): + New define_insn_and_split. + (bstrins_<mode>_for_ior_mask): Likewise. + (define_peephole2): Further optimize code sequence produced by + bstrins_<mode>_for_ior_mask if possible. + +2023-09-07 Richard Sandiford <richard.sandiford@arm.com> + + * lra-eliminations.cc (lra_eliminate_regs_1): Use simplify_gen_binary + rather than gen_rtx_PLUS. + +2023-09-07 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/111313 + * config/riscv/riscv-vsetvl.cc (pass_vsetvl::cleanup_earliest_vsetvls): Remove. + (pass_vsetvl::df_post_optimization): Remove incorrect function. + +2023-09-07 Tsukasa OI <research_trasio@irq.a4lg.com> + + * common/config/riscv/riscv-common.cc (riscv_ext_flag_table): + Parse 'XVentanaCondOps' extension. + * config/riscv/riscv-opts.h (MASK_XVENTANACONDOPS): New. + (TARGET_XVENTANACONDOPS): Ditto. + (TARGET_ZICOND_LIKE): New to represent targets with conditional + moves like 'Zicond'. It includes RV64 + 'XVentanaCondOps'. + * config/riscv/riscv.cc (riscv_rtx_costs): Replace TARGET_ZICOND + with TARGET_ZICOND_LIKE. + (riscv_expand_conditional_move): Ditto. + * config/riscv/riscv.md (mov<mode>cc): Replace TARGET_ZICOND with + TARGET_ZICOND_LIKE. + * config/riscv/riscv.opt: Add new riscv_xventana_subext. + * config/riscv/zicond.md: Modify description. + (eqz_ventana): New to match corresponding czero instructions. + (nez_ventana): Ditto. + (*czero.<eqz>.<GPR><X>): Emit a 'XVentanaCondOps' instruction if + 'Zicond' is not available but 'XVentanaCondOps' + RV64 is. + (*czero.<eqz>.<GPR><X>): Ditto. + (*czero.eqz.<GPR><X>.opt1): Ditto. + (*czero.nez.<GPR><X>.opt2): Ditto. + 2023-09-06 Ian Lance Taylor <iant@golang.org> PR go/111310 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 11df268..0799209 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20230907 +20230911 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 12c8578..2e04d4a 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,36 @@ +2023-09-09 benjamin priour <vultkayn@gcc.gnu.org> + + PR analyzer/96395 + * region-model.cc + (region_model::add_constraints_from_binop): binop_svalues around + LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR are now unwrapped. + +2023-09-07 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/110529 + * program-point.cc (program_point::on_edge): Don't reject + EDGE_ABNORMAL for computed gotos. + * region-model.cc (region_model::maybe_update_for_edge): Handle + computed goto statements. + (region_model::apply_constraints_for_ggoto): New. + * region-model.h (region_model::apply_constraints_for_ggoto): New decl. + * supergraph.cc (supernode::get_label): New. + * supergraph.h (supernode::get_label): New decl. + +2023-09-07 benjamin priour <vultkayn@gcc.gnu.org> + David Malcolm <dmalcolm@redhat.com> + + PR analyzer/110830 + * diagnostic-manager.cc + (compatible_epaths_p): New function. + (saved_diagnostic::supercedes_p): Now calls the above + to determine if the diagnostics do overlap and the superseding + may proceed. + +2023-09-07 David Malcolm <dmalcolm@redhat.com> + + * region-model.h: fix -Wunused-parameter warnings + 2023-09-06 David Malcolm <dmalcolm@redhat.com> PR analyzer/105899 diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 10fea48..0dd375d 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -887,6 +887,88 @@ saved_diagnostic::add_duplicate (saved_diagnostic *other) m_duplicates.safe_push (other); } +/* Walk up the sedges of each of the two paths. + If the two sequences of sedges do not perfectly correspond, + then paths are incompatible. + If there is at least one sedge that either cannot be paired up + or its counterpart is not equal, then the paths are incompatible + and this function returns FALSE. + Otherwise return TRUE. + + Incompatible paths: + + <cond Y> + / \ + / \ + true false + | | + ... ... + | | + ... stmt x + | + stmt x + + Both LHS_PATH and RHS_PATH final enodes should be + over the same gimple statement. */ + +static bool +compatible_epath_p (const exploded_path *lhs_path, + const exploded_path *rhs_path) +{ + gcc_assert (lhs_path); + gcc_assert (rhs_path); + gcc_assert (rhs_path->length () > 0); + gcc_assert (rhs_path->length () > 0); + int lhs_eedge_idx = lhs_path->length () - 1; + int rhs_eedge_idx = rhs_path->length () - 1; + const exploded_edge *lhs_eedge; + const exploded_edge *rhs_eedge; + + while (lhs_eedge_idx >= 0 && rhs_eedge_idx >= 0) + { + while (lhs_eedge_idx >= 0) + { + /* Find LHS_PATH's next superedge. */ + lhs_eedge = lhs_path->m_edges[lhs_eedge_idx]; + if (lhs_eedge->m_sedge) + break; + else + lhs_eedge_idx--; + } + while (rhs_eedge_idx >= 0) + { + /* Find RHS_PATH's next superedge. */ + rhs_eedge = rhs_path->m_edges[rhs_eedge_idx]; + if (rhs_eedge->m_sedge) + break; + else + rhs_eedge_idx--; + } + + if (lhs_eedge->m_sedge && rhs_eedge->m_sedge) + { + if (lhs_eedge->m_sedge != rhs_eedge->m_sedge) + /* Both superedges do not match. + Superedges are not dependent on the exploded path, so even + different epaths will have similar sedges if they follow + the same outcome of a conditional node. */ + return false; + + lhs_eedge_idx--; + rhs_eedge_idx--; + continue; + } + else if (lhs_eedge->m_sedge == nullptr && rhs_eedge->m_sedge == nullptr) + /* Both paths were drained up entirely. + No discriminant was found. */ + return true; + + /* A superedge was found for only one of the two paths. */ + return false; + } +} + + /* Return true if this diagnostic supercedes OTHER, and that OTHER should therefore not be emitted. */ @@ -896,7 +978,13 @@ saved_diagnostic::supercedes_p (const saved_diagnostic &other) const /* They should be at the same stmt. */ if (m_stmt != other.m_stmt) return false; - return m_d->supercedes_p (*other.m_d); + /* return early if OTHER won't be superseded anyway. */ + if (!m_d->supercedes_p (*other.m_d)) + return false; + + /* If the two saved_diagnostics' path are not compatible + then they cannot supersede one another. */ + return compatible_epath_p (m_best_epath.get (), other.m_best_epath.get ()); } /* Move any saved checker_events from this saved_diagnostic to diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc index f2d6490..d7db2f5 100644 --- a/gcc/analyzer/program-point.cc +++ b/gcc/analyzer/program-point.cc @@ -426,9 +426,22 @@ program_point::on_edge (exploded_graph &eg, { const cfg_superedge *cfg_sedge = as_a <const cfg_superedge *> (succ); - /* Reject abnormal edges; we special-case setjmp/longjmp. */ if (cfg_sedge->get_flags () & EDGE_ABNORMAL) - return false; + { + const supernode *src_snode = cfg_sedge->m_src; + if (gimple *last_stmt = src_snode->get_last_stmt ()) + if (last_stmt->code == GIMPLE_GOTO) + { + /* For the program_point aspect here, consider all + out-edges from goto stmts to be valid; we'll + consider state separately. */ + return true; + } + + /* Reject other kinds of abnormal edges; + we special-case setjmp/longjmp. */ + return false; + } } break; diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 999480e..da1ec7c 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -4458,6 +4458,10 @@ region_model::add_constraints_from_binop (const svalue *outer_lhs, case EQ_EXPR: case NE_EXPR: + case GE_EXPR: + case GT_EXPR: + case LE_EXPR: + case LT_EXPR: { /* ...and "(inner_lhs OP inner_rhs) == 0" then (inner_lhs OP inner_rhs) must have the same @@ -4997,7 +5001,7 @@ region_model::maybe_update_for_edge (const superedge &edge, if (last_stmt == NULL) return true; - /* Apply any constraints for conditionals/switch statements. */ + /* Apply any constraints for conditionals/switch/computed-goto statements. */ if (const gcond *cond_stmt = dyn_cast <const gcond *> (last_stmt)) { @@ -5013,6 +5017,12 @@ region_model::maybe_update_for_edge (const superedge &edge, ctxt, out); } + if (const ggoto *goto_stmt = dyn_cast <const ggoto *> (last_stmt)) + { + const cfg_superedge *cfg_sedge = as_a <const cfg_superedge *> (&edge); + return apply_constraints_for_ggoto (*cfg_sedge, goto_stmt, ctxt); + } + /* Apply any constraints due to an exception being thrown. */ if (const cfg_superedge *cfg_sedge = dyn_cast <const cfg_superedge *> (&edge)) if (cfg_sedge->get_flags () & EDGE_EH) @@ -5267,6 +5277,37 @@ region_model::apply_constraints_for_gswitch (const switch_cfg_superedge &edge, return sat; } +/* Given an edge reached by GOTO_STMT, determine appropriate constraints + for the edge to be taken. + + If they are feasible, add the constraints and return true. + + Return false if the constraints contradict existing knowledge + (and so the edge should not be taken). */ + +bool +region_model::apply_constraints_for_ggoto (const cfg_superedge &edge, + const ggoto *goto_stmt, + region_model_context *ctxt) +{ + tree dest = gimple_goto_dest (goto_stmt); + const svalue *dest_sval = get_rvalue (dest, ctxt); + + /* If we know we were jumping to a specific label. */ + if (tree dst_label = edge.m_dest->get_label ()) + { + const label_region *dst_label_reg + = m_mgr->get_region_for_label (dst_label); + const svalue *dst_label_ptr + = m_mgr->get_ptr_svalue (ptr_type_node, dst_label_reg); + + if (!add_constraint (dest_sval, EQ_EXPR, dst_label_ptr, ctxt)) + return false; + } + + return true; +} + /* Apply any constraints due to an exception being thrown at LAST_STMT. If they are feasible, add the constraints and return true. diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 625f688..62d4634 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -589,6 +589,9 @@ private: const gswitch *switch_stmt, region_model_context *ctxt, rejected_constraint **out); + bool apply_constraints_for_ggoto (const cfg_superedge &edge, + const ggoto *goto_stmt, + region_model_context *ctxt); bool apply_constraints_for_exception (const gimple *last_stmt, region_model_context *ctxt, rejected_constraint **out); @@ -793,8 +796,8 @@ class region_model_context class noop_region_model_context : public region_model_context { public: - bool warn (std::unique_ptr<pending_diagnostic> d, - const stmt_finder *custom_finder) override { return false; } + bool warn (std::unique_ptr<pending_diagnostic>, + const stmt_finder *) override { return false; } void add_note (std::unique_ptr<pending_note>) override; void add_event (std::unique_ptr<checker_event>) override; void on_svalue_leak (const svalue *) override {} @@ -1200,7 +1203,7 @@ class test_region_model_context : public noop_region_model_context { public: bool warn (std::unique_ptr<pending_diagnostic> d, - const stmt_finder *custom_finder) final override + const stmt_finder *) final override { m_diagnostics.safe_push (d.release ()); return true; diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc index a23ff15..31707e7 100644 --- a/gcc/analyzer/supergraph.cc +++ b/gcc/analyzer/supergraph.cc @@ -829,6 +829,19 @@ supernode::get_stmt_index (const gimple *stmt) const gcc_unreachable (); } +/* Get any label_decl for this supernode, or NULL_TREE if there isn't one. */ + +tree +supernode::get_label () const +{ + if (m_stmts.length () == 0) + return NULL_TREE; + const glabel *label_stmt = dyn_cast<const glabel *> (m_stmts[0]); + if (!label_stmt) + return NULL_TREE; + return gimple_label_label (label_stmt); +} + /* Get a string for PK. */ static const char * diff --git a/gcc/analyzer/supergraph.h b/gcc/analyzer/supergraph.h index f8b36d7..27ebd13 100644 --- a/gcc/analyzer/supergraph.h +++ b/gcc/analyzer/supergraph.h @@ -297,6 +297,8 @@ class supernode : public dnode<supergraph_traits> unsigned int get_stmt_index (const gimple *stmt) const; + tree get_label () const; + function * const m_fun; // alternatively could be stored as runs of indices within the supergraph const basic_block m_bb; gcall * const m_returning_call; // for handling the result of a returned call diff --git a/gcc/common/config/loongarch/loongarch-common.cc b/gcc/common/config/loongarch/loongarch-common.cc index c5ed37d..b690191 100644 --- a/gcc/common/config/loongarch/loongarch-common.cc +++ b/gcc/common/config/loongarch/loongarch-common.cc @@ -36,6 +36,7 @@ static const struct default_options loongarch_option_optimization_table[] = { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; diff --git a/gcc/config.gcc b/gcc/config.gcc index 0c8d756..9f086d1 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -5236,7 +5236,7 @@ case "${target}" in if test x${parse_state} = x"abi-base"; then # Base ABI type case ${component} in - lp64d | lp64f | lp64s) elem_tmp="ABI_BASE_$(tr a-z A-Z <<< ${component}),";; + lp64d | lp64f | lp64s) elem_tmp="ABI_BASE_$(echo ${component} | tr a-z A-Z),";; *) echo "Unknown base ABI \"${component}\" in --with-multilib-list." 1>&2 exit 1 diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc index 95d6194..154a2b2 100644 --- a/gcc/config/darwin.cc +++ b/gcc/config/darwin.cc @@ -3893,19 +3893,22 @@ darwin_function_section (tree decl, enum node_frequency freq, if (decl && DECL_SECTION_NAME (decl) != NULL) return get_named_section (decl, NULL, 0); + /* We always put unlikely executed stuff in the cold section; we have to put + this ahead of the global init section, since partitioning within a section + breaks some assumptions made in the DWARF handling. */ + if (freq == NODE_FREQUENCY_UNLIKELY_EXECUTED) + return (use_coal) ? darwin_sections[text_cold_coal_section] + : darwin_sections[text_cold_section]; + /* Intercept functions in global init; these are placed in separate sections. - FIXME: there should be some neater way to do this. */ + FIXME: there should be some neater way to do this, FIXME we should be able + to partition within a section. */ if (DECL_NAME (decl) && (startswith (IDENTIFIER_POINTER (DECL_NAME (decl)), "_GLOBAL__sub_I") || startswith (IDENTIFIER_POINTER (DECL_NAME (decl)), "__static_initialization_and_destruction"))) return darwin_sections[static_init_section]; - /* We always put unlikely executed stuff in the cold section. */ - if (freq == NODE_FREQUENCY_UNLIKELY_EXECUTED) - return (use_coal) ? darwin_sections[text_cold_coal_section] - : darwin_sections[text_cold_section]; - /* If we have LTO *and* feedback information, then let LTO handle the function ordering, it makes a better job (for normal, hot, startup and exit - hence the bailout for cold above). */ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 6d3ae8d..80b43fd 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -466,6 +466,10 @@ (define_mode_iterator VHF_AVX512VL [V32HF (V16HF "TARGET_AVX512VL") (V8HF "TARGET_AVX512VL")]) +(define_mode_iterator VHFBF_AVX512VL + [V32HF (V16HF "TARGET_AVX512VL") (V8HF "TARGET_AVX512VL") + V32BF (V16BF "TARGET_AVX512VL") (V8BF "TARGET_AVX512VL")]) + ;; All vector integer modes (define_mode_iterator VI [(V16SI "TARGET_AVX512F") (V8DI "TARGET_AVX512F") @@ -565,6 +569,11 @@ (define_mode_iterator VI2_AVX512VL [(V8HI "TARGET_AVX512VL") (V16HI "TARGET_AVX512VL") V32HI]) +(define_mode_iterator VI2HFBF_AVX512VL + [(V8HI "TARGET_AVX512VL") (V16HI "TARGET_AVX512VL") V32HI + (V8HF "TARGET_AVX512VL") (V16HF "TARGET_AVX512VL") V32HF + (V8BF "TARGET_AVX512VL") (V16BF "TARGET_AVX512VL") V32BF]) + (define_mode_iterator VI2H_AVX512VL [(V8HI "TARGET_AVX512VL") (V16HI "TARGET_AVX512VL") V32HI (V8SI "TARGET_AVX512VL") V16SI @@ -6480,6 +6489,14 @@ [(UNSPEC_COMPLEX_FMA_PAIR "fmaddc") (UNSPEC_COMPLEX_FCMA_PAIR "fcmaddc")]) +(define_int_attr int_comm + [(UNSPEC_COMPLEX_FMA "") + (UNSPEC_COMPLEX_FMA_PAIR "") + (UNSPEC_COMPLEX_FCMA "") + (UNSPEC_COMPLEX_FCMA_PAIR "") + (UNSPEC_COMPLEX_FMUL "%") + (UNSPEC_COMPLEX_FCMUL "")]) + (define_int_attr conj_op [(UNSPEC_COMPLEX_FMA "") (UNSPEC_COMPLEX_FCMA "_conj") @@ -6593,7 +6610,7 @@ (define_insn "fma_<complexopname>_<mode><sdc_maskz_name><round_name>" [(set (match_operand:VHF_AVX512VL 0 "register_operand" "=&v") (unspec:VHF_AVX512VL - [(match_operand:VHF_AVX512VL 1 "<round_nimm_predicate>" "%v") + [(match_operand:VHF_AVX512VL 1 "<round_nimm_predicate>" "<int_comm>v") (match_operand:VHF_AVX512VL 2 "<round_nimm_predicate>" "<round_constraint>") (match_operand:VHF_AVX512VL 3 "<round_nimm_predicate>" "0")] UNSPEC_COMPLEX_F_C_MA))] @@ -6658,7 +6675,7 @@ (define_insn "fma_<complexpairopname>_<mode>_pair" [(set (match_operand:VF1_AVX512VL 0 "register_operand" "=&v") (unspec:VF1_AVX512VL - [(match_operand:VF1_AVX512VL 1 "vector_operand" "%v") + [(match_operand:VF1_AVX512VL 1 "vector_operand" "<int_comm>v") (match_operand:VF1_AVX512VL 2 "bcst_vector_operand" "vmBr") (match_operand:VF1_AVX512VL 3 "vector_operand" "0")] UNSPEC_COMPLEX_F_C_MA_PAIR))] @@ -6727,7 +6744,7 @@ [(set (match_operand:VHF_AVX512VL 0 "register_operand" "=&v") (vec_merge:VHF_AVX512VL (unspec:VHF_AVX512VL - [(match_operand:VHF_AVX512VL 1 "nonimmediate_operand" "%v") + [(match_operand:VHF_AVX512VL 1 "nonimmediate_operand" "<int_comm>v") (match_operand:VHF_AVX512VL 2 "nonimmediate_operand" "<round_constraint>") (match_operand:VHF_AVX512VL 3 "register_operand" "0")] UNSPEC_COMPLEX_F_C_MA) @@ -6752,7 +6769,7 @@ (define_insn "<avx512>_<complexopname>_<mode><maskc_name><round_name>" [(set (match_operand:VHF_AVX512VL 0 "register_operand" "=&v") (unspec:VHF_AVX512VL - [(match_operand:VHF_AVX512VL 1 "nonimmediate_operand" "%v") + [(match_operand:VHF_AVX512VL 1 "nonimmediate_operand" "<int_comm>v") (match_operand:VHF_AVX512VL 2 "nonimmediate_operand" "<round_constraint>")] UNSPEC_COMPLEX_F_C_MUL))] "TARGET_AVX512FP16 && <round_mode512bit_condition>" @@ -26110,13 +26127,13 @@ (set_attr "mode" "<sseinsnmode>")]) (define_insn "<avx512>_permvar<mode><mask_name>" - [(set (match_operand:VI2_AVX512VL 0 "register_operand" "=v") - (unspec:VI2_AVX512VL - [(match_operand:VI2_AVX512VL 1 "nonimmediate_operand" "vm") + [(set (match_operand:VI2HFBF_AVX512VL 0 "register_operand" "=v") + (unspec:VI2HFBF_AVX512VL + [(match_operand:VI2HFBF_AVX512VL 1 "nonimmediate_operand" "vm") (match_operand:<sseintvecmode> 2 "register_operand" "v")] UNSPEC_VPERMVAR))] "TARGET_AVX512BW && <mask_mode512bit_condition>" - "vperm<ssemodesuffix>\t{%1, %2, %0<mask_operand3>|%0<mask_operand3>, %2, %1}" + "vpermw\t{%1, %2, %0<mask_operand3>|%0<mask_operand3>, %2, %1}" [(set_attr "type" "sselog") (set_attr "prefix" "<mask_prefix2>") (set_attr "mode" "<sseinsnmode>")]) @@ -26987,6 +27004,21 @@ (set_attr "prefix" "evex") (set_attr "mode" "<sseinsnmode>")]) +(define_insn "<avx512>_vpermt2var<mode>3<sd_maskz_name>" + [(set (match_operand:VHFBF_AVX512VL 0 "register_operand" "=v,v") + (unspec:VHFBF_AVX512VL + [(match_operand:<sseintvecmode> 1 "register_operand" "v,0") + (match_operand:VHFBF_AVX512VL 2 "register_operand" "0,v") + (match_operand:VHFBF_AVX512VL 3 "nonimmediate_operand" "vm,vm")] + UNSPEC_VPERMT2))] + "TARGET_AVX512BW" + "@ + vpermt2w\t{%3, %1, %0<sd_mask_op4>|%0<sd_mask_op4>, %1, %3} + vpermi2w\t{%3, %2, %0<sd_mask_op4>|%0<sd_mask_op4>, %2, %3}" + [(set_attr "type" "sselog") + (set_attr "prefix" "evex") + (set_attr "mode" "<sseinsnmode>")]) + (define_insn "<avx512>_vpermt2var<mode>3_mask" [(set (match_operand:VPERMI2 0 "register_operand" "=v") (vec_merge:VPERMI2 diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 6698414..845fad5 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -5191,6 +5191,20 @@ loongarch_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED, return true; } +static machine_mode +loongarch_mode_for_move_size (HOST_WIDE_INT size) +{ + switch (size) + { + case 32: + return V32QImode; + case 16: + return V16QImode; + } + + return int_mode_for_size (size * BITS_PER_UNIT, 0).require (); +} + /* Emit straight-line code to move LENGTH bytes from SRC to DEST. Assume that the areas do not overlap. */ @@ -5211,16 +5225,15 @@ loongarch_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length, emit two ld.d/st.d pairs, one ld.w/st.w pair, and one ld.b/st.b pair. For each load/store pair we use a dedicated register to keep the pipeline as populated as possible. */ - HOST_WIDE_INT num_reg = length / delta; - for (delta_cur = delta / 2; delta_cur != 0; delta_cur /= 2) - num_reg += !!(length & delta_cur); + gcc_assert (pow2p_hwi (delta)); + HOST_WIDE_INT num_reg = length / delta + popcount_hwi (length % delta); /* Allocate a buffer for the temporary registers. */ regs = XALLOCAVEC (rtx, num_reg); for (delta_cur = delta, i = 0, offs = 0; offs < length; delta_cur /= 2) { - mode = int_mode_for_size (delta_cur * BITS_PER_UNIT, 0).require (); + mode = loongarch_mode_for_move_size (delta_cur); for (; offs + delta_cur <= length; offs += delta_cur, i++) { @@ -5231,7 +5244,7 @@ loongarch_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length, for (delta_cur = delta, i = 0, offs = 0; offs < length; delta_cur /= 2) { - mode = int_mode_for_size (delta_cur * BITS_PER_UNIT, 0).require (); + mode = loongarch_mode_for_move_size (delta_cur); for (; offs + delta_cur <= length; offs += delta_cur, i++) loongarch_emit_move (adjust_address (dest, mode, offs), regs[i]); @@ -5326,8 +5339,8 @@ loongarch_expand_block_move (rtx dest, rtx src, rtx r_length, rtx r_align) HOST_WIDE_INT align = INTVAL (r_align); - if (!TARGET_STRICT_ALIGN || align > UNITS_PER_WORD) - align = UNITS_PER_WORD; + if (!TARGET_STRICT_ALIGN || align > LARCH_MAX_MOVE_PER_INSN) + align = LARCH_MAX_MOVE_PER_INSN; if (length <= align * LARCH_MAX_MOVE_OPS_STRAIGHT) { diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index 3fc9dc4..7e39120 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -1181,6 +1181,9 @@ typedef struct { least twice. */ #define LARCH_MAX_MOVE_OPS_STRAIGHT (LARCH_MAX_MOVE_OPS_PER_LOOP_ITER * 2) +#define LARCH_MAX_MOVE_PER_INSN \ + (ISA_HAS_LASX ? 32 : (ISA_HAS_LSX ? 16 : UNITS_PER_WORD)) + /* The base cost of a memcpy call, for MOVE_RATIO and friends. These values were determined experimentally by benchmarking with CSiBE. */ diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 75f641b..1dc6b52 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -750,15 +750,6 @@ [(set_attr "type" "imul") (set_attr "mode" "<MODE>")]) -(define_insn "mulsidi3_64bit" - [(set (match_operand:DI 0 "register_operand" "=r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_64BIT" - "mulw.d.w\t%0,%1,%2" - [(set_attr "type" "imul") - (set_attr "mode" "DI")]) - (define_insn "*mulsi3_extended" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI @@ -787,14 +778,14 @@ emit_insn (gen_muldi3 (low, operands[1], operands[2])); rtx high = gen_reg_rtx (DImode); - emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2])); + emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2])); emit_move_insn (gen_lowpart (DImode, operands[0]), low); emit_move_insn (gen_highpart (DImode, operands[0]), high); DONE; }) -(define_insn "<u>muldi3_highpart" +(define_insn "<su>muldi3_highpart" [(set (match_operand:DI 0 "register_operand" "=r") (truncate:DI (lshiftrt:TI @@ -809,22 +800,34 @@ (set_attr "mode" "DI")]) (define_expand "<u>mulsidi3" - [(set (match_operand:DI 0 "register_operand" "=r") + [(set (match_operand:DI 0 "register_operand") (mult:DI (any_extend:DI - (match_operand:SI 1 "register_operand" " r")) + (match_operand:SI 1 "register_operand")) (any_extend:DI - (match_operand:SI 2 "register_operand" " r"))))] - "!TARGET_64BIT" + (match_operand:SI 2 "register_operand"))))] + "" { - rtx temp = gen_reg_rtx (SImode); - emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); - emit_insn (gen_<u>mulsi3_highpart (loongarch_subword (operands[0], true), - operands[1], operands[2])); - emit_insn (gen_movsi (loongarch_subword (operands[0], false), temp)); - DONE; + if (!TARGET_64BIT) + { + rtx temp = gen_reg_rtx (SImode); + emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); + emit_insn (gen_<su>mulsi3_highpart (loongarch_subword (operands[0], true), + operands[1], operands[2])); + emit_insn (gen_movsi (loongarch_subword (operands[0], false), temp)); + DONE; + } }) -(define_insn "<u>mulsi3_highpart" +(define_insn "<u>mulsidi3_64bit" + [(set (match_operand:DI 0 "register_operand" "=r") + (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "r")) + (any_extend:DI (match_operand:SI 2 "register_operand" "r"))))] + "TARGET_64BIT" + "mulw.d.w<u>\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "DI")]) + +(define_insn "<su>mulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI @@ -833,11 +836,28 @@ (any_extend:DI (match_operand:SI 2 "register_operand" " r"))) (const_int 32))))] - "!TARGET_64BIT" + "" "mulh.w<u>\t%0,%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")]) +;; Under the LoongArch architecture, the mulh.w[u] instruction performs +;; sign extension by default, so the sign extension instruction can be +;; eliminated. +(define_peephole + [(set (match_operand:SI 0 "register_operand") + (truncate:SI + (lshiftrt:DI + (mult:DI (any_extend:DI + (match_operand:SI 1 "register_operand")) + (any_extend:DI + (match_operand:SI 2 "register_operand"))) + (const_int 32)))) + (set (match_operand:DI 3 "register_operand") + (sign_extend:DI (match_dup 0)))] + "TARGET_64BIT && REGNO (operands[0]) == REGNO (operands[3])" + "mulh.w<u>\t%0,%1,%2") + ;; ;; .................... ;; diff --git a/gcc/config/riscv/autovec-vls.md b/gcc/config/riscv/autovec-vls.md index 31b6c4a..6f48f7d 100644 --- a/gcc/config/riscv/autovec-vls.md +++ b/gcc/config/riscv/autovec-vls.md @@ -128,8 +128,12 @@ { emit_move_insn (operands[2], gen_int_mode (GET_MODE_NUNITS (<VLS_AVL_REG:MODE>mode), Pmode)); + unsigned insn_flags + = GET_MODE_CLASS (<VLS_AVL_REG:MODE>mode) == MODE_VECTOR_BOOL + ? riscv_vector::UNARY_MASK_OP + : riscv_vector::UNARY_OP; riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<VLS_AVL_REG:MODE>mode), - riscv_vector::UNARY_OP, operands, operands[2]); + insn_flags, operands, operands[2]); } DONE; } @@ -144,6 +148,14 @@ [(set_attr "type" "vmov") (set_attr "mode" "<MODE>")]) +(define_insn "*mov<mode>_vls" + [(set (match_operand:VLSB 0 "register_operand" "=vr") + (match_operand:VLSB 1 "register_operand" " vr"))] + "TARGET_VECTOR" + "vmv1r.v\t%0,%1" + [(set_attr "type" "vmov") + (set_attr "mode" "<MODE>")]) + (define_expand "movmisalign<mode>" [(set (match_operand:VLS 0 "nonimmediate_operand") (match_operand:VLS 1 "general_operand"))] diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 98cd0c0..50ed1a9 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -354,9 +354,9 @@ ;; ------------------------------------------------------------------------- (define_expand "vec_perm<mode>" - [(match_operand:V 0 "register_operand") - (match_operand:V 1 "register_operand") - (match_operand:V 2 "register_operand") + [(match_operand:V_VLS 0 "register_operand") + (match_operand:V_VLS 1 "register_operand") + (match_operand:V_VLS 2 "register_operand") (match_operand:<VINDEX> 3 "vector_perm_operand")] "TARGET_VECTOR && GET_MODE_NUNITS (<MODE>mode).is_constant ()" { diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 1544ef4..431b329 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -283,7 +283,7 @@ [(set_attr "type" "bitmanip,load") (set_attr "mode" "<GPR:MODE>")]) -(define_insn "*extend<SHORT:mode><SUPERQI:mode>2_zbb" +(define_insn "*extend<SHORT:mode><SUPERQI:mode>2_bitmanip" [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] @@ -294,17 +294,6 @@ [(set_attr "type" "bitmanip,load") (set_attr "mode" "<SUPERQI:MODE>")]) -(define_insn "*zero_extendhi<GPR:mode>2_zbb" - [(set (match_operand:GPR 0 "register_operand" "=r,r") - (zero_extend:GPR - (match_operand:HI 1 "nonimmediate_operand" " r,m")))] - "TARGET_ZBB" - "@ - zext.h\t%0,%1 - lhu\t%0,%1" - [(set_attr "type" "bitmanip,load") - (set_attr "mode" "HI")]) - (define_expand "rotrdi3" [(set (match_operand:DI 0 "register_operand") (rotatert:DI (match_operand:DI 1 "register_operand") diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 6dbf6b9..e91a55e 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -498,8 +498,8 @@ enum floating_point_rounding_mode get_frm_mode (rtx); opt_machine_mode vectorize_related_mode (machine_mode, scalar_mode, poly_uint64); unsigned int autovectorize_vector_modes (vec<machine_mode> *, bool); -hash_set<basic_block> get_all_predecessors (basic_block); -hash_set<basic_block> get_all_successors (basic_block); +bool cmp_lmul_le_one (machine_mode); +bool cmp_lmul_gt_one (machine_mode); } /* We classify builtin types into two classes: diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 1ca3f1d..4d95bd7 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2647,7 +2647,8 @@ shuffle_compress_patterns (struct expand_vec_perm_d *d) For index = { 0, 2, 5, 6}, we need to slide op1 up before we apply compress approach. */ - bool need_slideup_p = maybe_ne (d->perm[vlen - 1], 2 * vec_len - 1); + bool need_slideup_p = maybe_ne (d->perm[vlen - 1], 2 * vec_len - 1) + && !const_vec_duplicate_p (d->op1); /* If we leave it directly be handled by general gather, the code sequence will be: @@ -2792,14 +2793,9 @@ shuffle_generic_patterns (struct expand_vec_perm_d *d) if (!pow2p_hwi (d->perm.encoding().npatterns ())) return false; - /* For constant size indices, we dont't need to handle it here. - Just leave it to vec_perm<mode>. */ - if (d->perm.length ().is_constant ()) - return false; - /* Permuting two SEW8 variable-length vectors need vrgatherei16.vv. Otherwise, it could overflow the index range. */ - if (GET_MODE_INNER (d->vmode) == QImode + if (!nunits.is_constant () && GET_MODE_INNER (d->vmode) == QImode && !get_vector_mode (HImode, nunits).exists (&sel_mode)) return false; @@ -2808,7 +2804,12 @@ shuffle_generic_patterns (struct expand_vec_perm_d *d) return true; rtx sel = vec_perm_indices_to_rtx (sel_mode, d->perm); - expand_vec_perm (d->target, d->op0, d->op1, force_reg (sel_mode, sel)); + /* 'mov<mode>' generte interleave vector. */ + if (!nunits.is_constant ()) + sel = force_reg (sel_mode, sel); + /* Some FIXED-VLMAX/VLS vector permutation situations call targethook + instead of expand vec_perm<mode>, we handle it directly. */ + expand_vec_perm (d->target, d->op0, d->op1, sel); return true; } @@ -3387,52 +3388,26 @@ expand_fold_extract_last (rtx *ops) emit_label (end_label); } -hash_set<basic_block> -get_all_predecessors (basic_block bb) +/* Return true if the LMUL of comparison less than or equal to one. */ +bool +cmp_lmul_le_one (machine_mode mode) { - hash_set<basic_block> blocks; - auto_vec<basic_block> work_list; - hash_set<basic_block> visited_list; - work_list.safe_push (bb); - - while (!work_list.is_empty ()) - { - basic_block new_bb = work_list.pop (); - visited_list.add (new_bb); - edge e; - edge_iterator ei; - FOR_EACH_EDGE (e, ei, new_bb->preds) - { - if (!visited_list.contains (e->src)) - work_list.safe_push (e->src); - blocks.add (e->src); - } - } - return blocks; + if (riscv_v_ext_vector_mode_p (mode)) + return known_le (GET_MODE_SIZE (mode), BYTES_PER_RISCV_VECTOR); + else if (riscv_v_ext_vls_mode_p (mode)) + return known_le (GET_MODE_BITSIZE (mode), TARGET_MIN_VLEN); + return false; } -hash_set<basic_block> -get_all_successors (basic_block bb) +/* Return true if the LMUL of comparison greater than one. */ +bool +cmp_lmul_gt_one (machine_mode mode) { - hash_set<basic_block> blocks; - auto_vec<basic_block> work_list; - hash_set<basic_block> visited_list; - work_list.safe_push (bb); - - while (!work_list.is_empty ()) - { - basic_block new_bb = work_list.pop (); - visited_list.add (new_bb); - edge e; - edge_iterator ei; - FOR_EACH_EDGE (e, ei, new_bb->succs) - { - if (!visited_list.contains (e->dest)) - work_list.safe_push (e->dest); - blocks.add (e->dest); - } - } - return blocks; + if (riscv_v_ext_vector_mode_p (mode)) + return known_gt (GET_MODE_SIZE (mode), BYTES_PER_RISCV_VECTOR); + else if (riscv_v_ext_vls_mode_p (mode)) + return known_gt (GET_MODE_BITSIZE (mode), TARGET_MIN_VLEN); + return false; } } // namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index ae362a3..f81361c 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -3438,7 +3438,7 @@ pass_vsetvl::vsetvl_fusion (void) m_vector_manager->vector_kill, m_vector_manager->vector_earliest); changed_p |= earliest_fusion (); - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "\nEARLIEST fusion %d\n", fusion_no); m_vector_manager->dump (dump_file); @@ -3720,7 +3720,7 @@ pass_vsetvl::pre_vsetvl (void) /* We should dump the information before CFG is changed. Otherwise it will produce ICE (internal compiler error). */ - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) m_vector_manager->dump (dump_file); refine_vsetvls (); @@ -4054,7 +4054,7 @@ pass_vsetvl::global_eliminate_vsetvl_insn (const bb_info *bb) const } /* Step1: Reshape the VL/VTYPE status to make sure everything compatible. */ - hash_set<basic_block> pred_cfg_bbs = get_all_predecessors (cfg_bb); + auto_vec<basic_block> pred_cfg_bbs = get_dominated_by (CDI_POST_DOMINATORS, cfg_bb); FOR_EACH_EDGE (e, ei, cfg_bb->preds) { sbitmap avout = m_vector_manager->vector_avout[e->src->index]; @@ -4243,6 +4243,7 @@ pass_vsetvl::init (void) { /* Initialization of RTL_SSA. */ calculate_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_POST_DOMINATORS); df_analyze (); crtl->ssa = new function_info (cfun); } @@ -4250,7 +4251,7 @@ pass_vsetvl::init (void) m_vector_manager = new vector_infos_manager (); compute_probabilities (); - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "\nPrologue: Initialize vector infos\n"); m_vector_manager->dump (dump_file); @@ -4264,6 +4265,7 @@ pass_vsetvl::done (void) { /* Finalization of RTL_SSA. */ free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); if (crtl->ssa->perform_pending_updates ()) cleanup_cfg (0); delete crtl->ssa; @@ -4334,7 +4336,7 @@ pass_vsetvl::lazy_vsetvl (void) fprintf (dump_file, "\nPhase 1: Compute local backward vector infos\n"); for (const bb_info *bb : crtl->ssa->bbs ()) compute_local_backward_infos (bb); - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) m_vector_manager->dump (dump_file); /* Phase 2 - Emit vsetvl instructions within each basic block according to @@ -4344,7 +4346,7 @@ pass_vsetvl::lazy_vsetvl (void) "\nPhase 2: Emit vsetvl instruction within each block\n"); for (const bb_info *bb : crtl->ssa->bbs ()) emit_local_forward_vsetvls (bb); - if (dump_file) + if (dump_file && (dump_flags & TDF_DETAILS)) m_vector_manager->dump (dump_file); /* Phase 3 - Propagate demanded info across blocks. */ diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index fb96493..12926b2 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4414,7 +4414,7 @@ riscv_pass_in_vector_p (const_tree type) { static int warned = 0; - if (type && riscv_v_ext_mode_p (TYPE_MODE (type)) && !warned) + if (type && riscv_vector::lookup_vector_type_attribute (type) && !warned) { warning (OPT_Wpsabi, "ABI for the vector type is currently in experimental stage and " @@ -5387,7 +5387,7 @@ riscv_print_operand (FILE *file, rtx op, int letter) 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv). 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi). 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */ - if (riscv_v_ext_vector_mode_p (mode)) + if (riscv_v_ext_mode_p (mode)) { if (REG_P (op)) asm_fprintf (file, "v"); @@ -7548,7 +7548,7 @@ riscv_hard_regno_nregs (unsigned int regno, machine_mode mode) /* For VLS modes, we allocate registers according to TARGET_MIN_VLEN. */ if (riscv_v_ext_vls_mode_p (mode)) { - int size = GET_MODE_SIZE (mode).to_constant (); + int size = GET_MODE_BITSIZE (mode).to_constant (); if (size < TARGET_MIN_VLEN) return 1; else @@ -9473,7 +9473,7 @@ riscv_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode, rtx target, rtx op0, rtx op1, const vec_perm_indices &sel) { - if (TARGET_VECTOR && riscv_v_ext_vector_mode_p (vmode)) + if (TARGET_VECTOR && riscv_v_ext_mode_p (vmode)) return riscv_vector::expand_vec_perm_const (vmode, op_mode, target, op0, op1, sel); diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 14dc21b..b630b51 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -239,7 +239,8 @@ V1DI,V2DI,V4DI,V8DI,V16DI,V32DI,V64DI,V128DI,V256DI,V512DI, V1HF,V2HF,V4HF,V8HF,V16HF,V32HF,V64HF,V128HF,V256HF,V512HF,V1024HF,V2048HF, V1SF,V2SF,V4SF,V8SF,V16SF,V32SF,V64SF,V128SF,V256SF,V512SF,V1024SF, - V1DF,V2DF,V4DF,V8DF,V16DF,V32DF,V64DF,V128DF,V256DF,V512DF" + V1DF,V2DF,V4DF,V8DF,V16DF,V32DF,V64DF,V128DF,V256DF,V512DF, + V1BI,V2BI,V4BI,V8BI,V16BI,V32BI,V64BI,V128BI,V256BI,V512BI,V1024BI,V2048BI,V4096BI" (const_string "unknown")) ;; True if the main data type is twice the size of a word. diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 569e9af..6f769c3 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -295,7 +295,7 @@ EnumValue Enum(riscv_autovec_preference) String(fixed-vlmax) Value(RVV_FIXED_VLMAX) -param=riscv-autovec-preference= -Target RejectNegative Joined Enum(riscv_autovec_preference) Var(riscv_autovec_preference) Init(NO_AUTOVEC) +Target RejectNegative Joined Enum(riscv_autovec_preference) Var(riscv_autovec_preference) Init(RVV_SCALABLE) -param=riscv-autovec-preference=<string> Set the preference of auto-vectorization in the RISC-V port. Enum diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 29f98de..2287b75 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -58,14 +58,25 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "<GPR:MODE>")]) -(define_insn "*extend<SHORT:mode><SUPERQI:mode>2_th_ext" +(define_insn "*extendhi<SUPERQI:mode>2_th_ext" [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI - (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] + (match_operand:HI 1 "nonimmediate_operand" "r,m")))] "TARGET_XTHEADBB" "@ th.ext\t%0,%1,15,0 - l<SHORT:size>\t%0,%1" + lh\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "<SUPERQI:MODE>")]) + +(define_insn "*extendqi<SUPERQI:mode>2_th_ext" + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + (sign_extend:SUPERQI + (match_operand:QI 1 "nonimmediate_operand" "r,m")))] + "TARGET_XTHEADBB" + "@ + th.ext\t%0,%1,7,0 + lb\t%0,%1" [(set_attr "type" "bitmanip,load") (set_attr "mode" "<SUPERQI:MODE>")]) @@ -90,7 +101,7 @@ th.extu\t%0,%1,31,0 lwu\t%0,%1" [(set_attr "type" "bitmanip,load") - (set_attr "mode" "SI")]) + (set_attr "mode" "DI")]) (define_insn "*zero_extendhi<GPR:mode>2_th_extu" [(set (match_operand:GPR 0 "register_operand" "=r,r") @@ -100,7 +111,7 @@ th.extu\t%0,%1,15,0 lhu\t%0,%1" [(set_attr "type" "bitmanip,load") - (set_attr "mode" "HI")]) + (set_attr "mode" "<GPR:MODE>")]) (define_insn "*th_clz<mode>2" [(set (match_operand:X 0 "register_operand" "=r") diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index caef815..2f7f7cb 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -376,6 +376,85 @@ (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") + + (V1QI "TARGET_VECTOR_VLS") + (V2QI "TARGET_VECTOR_VLS") + (V4QI "TARGET_VECTOR_VLS") + (V8QI "TARGET_VECTOR_VLS") + (V16QI "TARGET_VECTOR_VLS") + (V32QI "TARGET_VECTOR_VLS") + (V64QI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V128QI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V256QI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V512QI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V1024QI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V2048QI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V1HI "TARGET_VECTOR_VLS") + (V2HI "TARGET_VECTOR_VLS") + (V4HI "TARGET_VECTOR_VLS") + (V8HI "TARGET_VECTOR_VLS") + (V16HI "TARGET_VECTOR_VLS") + (V32HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V64HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V128HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V256HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V512HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V1024HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V2048HI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096") + (V1SI "TARGET_VECTOR_VLS") + (V2SI "TARGET_VECTOR_VLS") + (V4SI "TARGET_VECTOR_VLS") + (V8SI "TARGET_VECTOR_VLS") + (V16SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V32SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V64SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V128SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V256SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V512SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V1024SI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096") + (V1DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V2DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V4DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") + (V8DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64") + (V16DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 128") + (V32DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 256") + (V64DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 512") + (V128DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 1024") + (V256DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 2048") + (V512DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096") + (V1HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") + (V2HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") + (V4HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") + (V8HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") + (V16HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") + (V32HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") + (V64HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") + (V128HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 256") + (V256HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 512") + (V512HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 1024") + (V1024HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 2048") + (V2048HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 4096") + (V1SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") + (V2SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") + (V4SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") + (V8SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") + (V16SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64") + (V32SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128") + (V64SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 256") + (V128SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 512") + (V256SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 1024") + (V512SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 2048") + (V1024SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 4096") + (V1DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V2DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V4DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") + (V8DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 64") + (V16DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + (V32DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 256") + (V64DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 512") + (V128DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 1024") + (V256DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 2048") + (V512DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096") ]) (define_mode_iterator VI [ @@ -456,18 +535,18 @@ (RVVM8DF "TARGET_VECTOR_ELEN_FP_64") (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") - (V1HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V2HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V4HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V8HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V16HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V32HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (V64HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (V128HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 256") - (V256HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 512") - (V512HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 1024") - (V1024HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 2048") - (V2048HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 4096") + (V1HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V2HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V4HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V8HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V16HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V32HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 64") + (V64HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 128") + (V128HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 256") + (V256HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 512") + (V512HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 1024") + (V1024HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 2048") + (V2048HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 4096") (V1SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") (V2SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") (V4SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") @@ -646,6 +725,7 @@ (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64") (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64") + (V1DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") (V2DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") (V4DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64") (V8DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 64") @@ -795,6 +875,23 @@ (RVVMF64BI "TARGET_MIN_VLEN > 32") RVVMF32BI RVVMF16BI RVVMF8BI RVVMF4BI RVVMF2BI RVVM1BI ]) +(define_mode_iterator VB_VLS [ + (RVVMF64BI "TARGET_MIN_VLEN > 32") RVVMF32BI RVVMF16BI RVVMF8BI RVVMF4BI RVVMF2BI RVVM1BI + (V1BI "TARGET_VECTOR_VLS") + (V2BI "TARGET_VECTOR_VLS") + (V4BI "TARGET_VECTOR_VLS") + (V8BI "TARGET_VECTOR_VLS") + (V16BI "TARGET_VECTOR_VLS") + (V32BI "TARGET_VECTOR_VLS") + (V64BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V128BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V256BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V512BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V1024BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V2048BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V4096BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096") +]) + (define_mode_iterator VWEXTI [ RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_MIN_VLEN > 32") @@ -1183,6 +1280,86 @@ (RVVM8DI "RVVM8DI") (RVVM4DI "RVVM4DI") (RVVM2DI "RVVM2DI") (RVVM1DI "RVVM1DI") (RVVM8DF "RVVM8DI") (RVVM4DF "RVVM4DI") (RVVM2DF "RVVM2DI") (RVVM1DF "RVVM1DI") + + (V1QI "V1QI") + (V2QI "V2QI") + (V4QI "V4QI") + (V8QI "V8QI") + (V16QI "V16QI") + (V32QI "V32QI") + (V64QI "V64QI") + (V128QI "V128QI") + (V256QI "V256QI") + (V512QI "V512QI") + (V1024QI "V1024QI") + (V2048QI "V2048QI") + (V4096QI "V4096QI") + (V1HI "V1HI") + (V2HI "V2HI") + (V4HI "V4HI") + (V8HI "V8HI") + (V16HI "V16HI") + (V32HI "V32HI") + (V64HI "V64HI") + (V128HI "V128HI") + (V256HI "V256HI") + (V512HI "V512HI") + (V1024HI "V1024HI") + (V2048HI "V2048HI") + (V1SI "V1SI") + (V2SI "V2SI") + (V4SI "V4SI") + (V8SI "V8SI") + (V16SI "V16SI") + (V32SI "V32SI") + (V64SI "V64SI") + (V128SI "V128SI") + (V256SI "V256SI") + (V512SI "V512SI") + (V1024SI "V1024SI") + (V1DI "V1DI") + (V2DI "V2DI") + (V4DI "V4DI") + (V8DI "V8DI") + (V16DI "V16DI") + (V32DI "V32DI") + (V64DI "V64DI") + (V128DI "V128DI") + (V256DI "V256DI") + (V512DI "V512DI") + (V1HF "V1HI") + (V2HF "V2HI") + (V4HF "V4HI") + (V8HF "V8HI") + (V16HF "V16HI") + (V32HF "V32HI") + (V64HF "V64HI") + (V128HF "V128HI") + (V256HF "V256HI") + (V512HF "V512HI") + (V1024HF "V1024HI") + (V2048HF "V2048HI") + (V1SF "V1SI") + (V2SF "V2SI") + (V4SF "V4SI") + (V8SF "V8SI") + (V16SF "V16SI") + (V32SF "V32SI") + (V64SF "V64SI") + (V128SF "V128SI") + (V256SF "V256SI") + (V512SF "V512SI") + (V1024SF "V1024SI") + (V1DF "V1DI") + (V2DF "V2DI") + (V4DF "V4DI") + (V8DF "V8DI") + (V16DF "V16DI") + (V32DF "V32DI") + (V64DF "V64DI") + (V128DF "V128DI") + (V256DF "V256DI") + (V512DF "V512DI") ]) (define_mode_attr VINDEXEI16 [ @@ -1199,6 +1376,85 @@ (RVVM8SF "RVVM4HI") (RVVM4SF "RVVM2HI") (RVVM2SF "RVVM1HI") (RVVM1SF "RVVMF2HI") (RVVMF2SF "RVVMF4HI") (RVVM8DF "RVVM2HI") (RVVM4DF "RVVM1HI") (RVVM2DF "RVVMF2HI") (RVVM1DF "RVVMF4HI") + + (V1QI "V1HI") + (V2QI "V2HI") + (V4QI "V4HI") + (V8QI "V8HI") + (V16QI "V16HI") + (V32QI "V32HI") + (V64QI "V64HI") + (V128QI "V128HI") + (V256QI "V256HI") + (V512QI "V512HI") + (V1024QI "V1024HI") + (V2048QI "V2048HI") + (V1HI "V1HI") + (V2HI "V2HI") + (V4HI "V4HI") + (V8HI "V8HI") + (V16HI "V16HI") + (V32HI "V32HI") + (V64HI "V64HI") + (V128HI "V128HI") + (V256HI "V256HI") + (V512HI "V512HI") + (V1024HI "V1024HI") + (V2048HI "V2048HI") + (V1SI "V1HI") + (V2SI "V2HI") + (V4SI "V4HI") + (V8SI "V8HI") + (V16SI "V16HI") + (V32SI "V32HI") + (V64SI "V64HI") + (V128SI "V128HI") + (V256SI "V256HI") + (V512SI "V512HI") + (V1024SI "V1024HI") + (V1DI "V1HI") + (V2DI "V2HI") + (V4DI "V4HI") + (V8DI "V8HI") + (V16DI "V16HI") + (V32DI "V32HI") + (V64DI "V64HI") + (V128DI "V128HI") + (V256DI "V256HI") + (V512DI "V512HI") + (V1HF "V1HI") + (V2HF "V2HI") + (V4HF "V4HI") + (V8HF "V8HI") + (V16HF "V16HF") + (V32HF "V32HI") + (V64HF "V64HI") + (V128HF "V128HI") + (V256HF "V256HI") + (V512HF "V512HI") + (V1024HF "V1024HI") + (V2048HF "V2048HI") + (V1SF "V1HI") + (V2SF "V2HI") + (V4SF "V4HI") + (V8SF "V8HI") + (V16SF "V16HI") + (V32SF "V32HI") + (V64SF "V64HI") + (V128SF "V128HI") + (V256SF "V256HI") + (V512SF "V512HI") + (V1024SF "V1024HI") + (V1DF "V1HI") + (V2DF "V2HI") + (V4DF "V4HI") + (V8DF "V8HI") + (V16DF "V16HI") + (V32DF "V32HI") + (V64DF "V64HI") + (V128DF "V128HI") + (V256DF "V256HI") + (V512DF "V512HI") ]) (define_mode_attr VM [ @@ -1570,11 +1826,11 @@ (RVVM8DF "SF") (RVVM4DF "SF") (RVVM2DF "SF") (RVVM1DF "SF") ;; VLS modes. - (V2HI "QI") (V4HI "QI") (V8HI "QI") (V16HI "QI") (V32HI "QI") (V64HI "QI") (V128HI "QI") (V256HI "QI") + (V1HI "QI") (V2HI "QI") (V4HI "QI") (V8HI "QI") (V16HI "QI") (V32HI "QI") (V64HI "QI") (V128HI "QI") (V256HI "QI") (V512HI "QI") (V1024HI "QI") (V2048HI "QI") - (V2SI "HI") (V4SI "HI") (V8SI "HI") (V16SI "HI") (V32SI "HI") (V64SI "HI") (V128SI "HI") (V256SI "HI") + (V1SI "HI") (V2SI "HI") (V4SI "HI") (V8SI "HI") (V16SI "HI") (V32SI "HI") (V64SI "HI") (V128SI "HI") (V256SI "HI") (V512SI "HI") (V1024SI "HI") - (V2DI "SI") (V4DI "SI") (V8DI "SI") (V16DI "SI") (V32DI "SI") (V64DI "SI") (V128DI "SI") (V256DI "SI") (V512DI "SI") + (V1DI "SI") (V2DI "SI") (V4DI "SI") (V8DI "SI") (V16DI "SI") (V32DI "SI") (V64DI "SI") (V128DI "SI") (V256DI "SI") (V512DI "SI") ]) (define_mode_attr nf [ @@ -1928,10 +2184,30 @@ (define_mode_attr VDEMOTE [ (RVVM8DI "RVVM8SI") (RVVM4DI "RVVM4SI") (RVVM2DI "RVVM2SI") (RVVM1DI "RVVM1SI") + (V1DI "V1SI") + (V2DI "V2SI") + (V4DI "V4SI") + (V8DI "V8SI") + (V16DI "V16SI") + (V32DI "V32SI") + (V64DI "V64SI") + (V128DI "V128SI") + (V256DI "V256SI") + (V512DI "V512SI") ]) (define_mode_attr VMDEMOTE [ (RVVM8DI "RVVMF4BI") (RVVM4DI "RVVMF8BI") (RVVM2DI "RVVMF16BI") (RVVM1DI "RVVMF32BI") + (V1DI "V1BI") + (V2DI "V2BI") + (V4DI "V4BI") + (V8DI "V8BI") + (V16DI "V16BI") + (V32DI "V32BI") + (V64DI "V64BI") + (V128DI "V128BI") + (V256DI "V256BI") + (V512DI "V512BI") ]) (define_mode_attr gs_extension [ @@ -2408,6 +2684,21 @@ (V256DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 2048") (V512DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096")]) +(define_mode_iterator VLSB [ + (V1BI "TARGET_VECTOR_VLS") + (V2BI "TARGET_VECTOR_VLS") + (V4BI "TARGET_VECTOR_VLS") + (V8BI "TARGET_VECTOR_VLS") + (V16BI "TARGET_VECTOR_VLS") + (V32BI "TARGET_VECTOR_VLS") + (V64BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V128BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V256BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V512BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V1024BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V2048BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V4096BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096")]) + ;; VLS modes that has NUNITS < 32. (define_mode_iterator VLS_AVL_IMM [ (V1QI "TARGET_VECTOR_VLS") @@ -2444,7 +2735,13 @@ (V2DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") (V4DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64") (V8DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 64") - (V16DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")]) + (V16DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128") + + (V1BI "TARGET_VECTOR_VLS") + (V2BI "TARGET_VECTOR_VLS") + (V4BI "TARGET_VECTOR_VLS") + (V8BI "TARGET_VECTOR_VLS") + (V16BI "TARGET_VECTOR_VLS")]) ;; VLS modes that has NUNITS >= 32. (define_mode_iterator VLS_AVL_REG [ @@ -2491,7 +2788,16 @@ (V64DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 512") (V128DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 1024") (V256DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 2048") - (V512DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096")]) + (V512DF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 4096") + + (V32BI "TARGET_VECTOR_VLS") + (V64BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 64") + (V128BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 128") + (V256BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 256") + (V512BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 512") + (V1024BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 1024") + (V2048BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 2048") + (V4096BI "TARGET_VECTOR_VLS && TARGET_MIN_VLEN >= 4096")]) (define_mode_iterator VLSI [ (V1QI "TARGET_VECTOR_VLS") @@ -2542,18 +2848,18 @@ (V512DI "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN >= 4096")]) (define_mode_iterator VLSF [ - (V1HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V2HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V4HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V8HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V16HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16") - (V32HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64") - (V64HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128") - (V128HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 256") - (V256HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 512") - (V512HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 1024") - (V1024HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 2048") - (V2048HF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 4096") + (V1HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V2HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V4HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V8HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V16HF "TARGET_VECTOR_VLS && TARGET_ZVFH") + (V32HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 64") + (V64HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 128") + (V128HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 256") + (V256HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 512") + (V512HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 1024") + (V1024HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 2048") + (V2048HF "TARGET_VECTOR_VLS && TARGET_ZVFH && TARGET_MIN_VLEN >= 4096") (V1SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") (V2SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") (V4SF "TARGET_VECTOR_VLS && TARGET_VECTOR_ELEN_FP_32") diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index fc985ff..58e659e 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -93,7 +93,8 @@ RVVM2x4QI,RVVM1x4QI,RVVMF2x4QI,RVVMF4x4QI,RVVMF8x4QI,\ RVVM2x3QI,RVVM1x3QI,RVVMF2x3QI,RVVMF4x3QI,RVVMF8x3QI,\ RVVM4x2QI,RVVM2x2QI,RVVM1x2QI,RVVMF2x2QI,RVVMF4x2QI,RVVMF8x2QI,\ - V1QI,V2QI,V4QI,V8QI,V16QI,V32QI,V64QI,V128QI,V256QI,V512QI,V1024QI,V2048QI,V4096QI") + V1QI,V2QI,V4QI,V8QI,V16QI,V32QI,V64QI,V128QI,V256QI,V512QI,V1024QI,V2048QI,V4096QI,\ + V1BI,V2BI,V4BI,V8BI,V16BI,V32BI,V64BI,V128BI,V256BI,V512BI,V1024BI,V2048BI,V4096BI") (const_int 8) (eq_attr "mode" "RVVM8HI,RVVM4HI,RVVM2HI,RVVM1HI,RVVMF2HI,RVVMF4HI,\ RVVM1x8HI,RVVMF2x8HI,RVVMF4x8HI,\ @@ -330,19 +331,19 @@ (eq_attr "mode" "RVVM1x2DF") (symbol_ref "riscv_vector::LMUL_1") ;; VLS modes. - (eq_attr "mode" "V1QI") (symbol_ref "riscv_vector::get_vlmul(E_V1QImode)") - (eq_attr "mode" "V2QI") (symbol_ref "riscv_vector::get_vlmul(E_V2QImode)") - (eq_attr "mode" "V4QI") (symbol_ref "riscv_vector::get_vlmul(E_V4QImode)") - (eq_attr "mode" "V8QI") (symbol_ref "riscv_vector::get_vlmul(E_V8QImode)") - (eq_attr "mode" "V16QI") (symbol_ref "riscv_vector::get_vlmul(E_V16QImode)") - (eq_attr "mode" "V32QI") (symbol_ref "riscv_vector::get_vlmul(E_V32QImode)") - (eq_attr "mode" "V64QI") (symbol_ref "riscv_vector::get_vlmul(E_V64QImode)") - (eq_attr "mode" "V128QI") (symbol_ref "riscv_vector::get_vlmul(E_V128QImode)") - (eq_attr "mode" "V256QI") (symbol_ref "riscv_vector::get_vlmul(E_V256QImode)") - (eq_attr "mode" "V512QI") (symbol_ref "riscv_vector::get_vlmul(E_V512QImode)") - (eq_attr "mode" "V1024QI") (symbol_ref "riscv_vector::get_vlmul(E_V1024QImode)") - (eq_attr "mode" "V2048QI") (symbol_ref "riscv_vector::get_vlmul(E_V2048QImode)") - (eq_attr "mode" "V4096QI") (symbol_ref "riscv_vector::get_vlmul(E_V4096QImode)") + (eq_attr "mode" "V1QI,V1BI") (symbol_ref "riscv_vector::get_vlmul(E_V1QImode)") + (eq_attr "mode" "V2QI,V2BI") (symbol_ref "riscv_vector::get_vlmul(E_V2QImode)") + (eq_attr "mode" "V4QI,V4BI") (symbol_ref "riscv_vector::get_vlmul(E_V4QImode)") + (eq_attr "mode" "V8QI,V8BI") (symbol_ref "riscv_vector::get_vlmul(E_V8QImode)") + (eq_attr "mode" "V16QI,V16BI") (symbol_ref "riscv_vector::get_vlmul(E_V16QImode)") + (eq_attr "mode" "V32QI,V32BI") (symbol_ref "riscv_vector::get_vlmul(E_V32QImode)") + (eq_attr "mode" "V64QI,V64BI") (symbol_ref "riscv_vector::get_vlmul(E_V64QImode)") + (eq_attr "mode" "V128QI,V128BI") (symbol_ref "riscv_vector::get_vlmul(E_V128QImode)") + (eq_attr "mode" "V256QI,V256BI") (symbol_ref "riscv_vector::get_vlmul(E_V256QImode)") + (eq_attr "mode" "V512QI,V512BI") (symbol_ref "riscv_vector::get_vlmul(E_V512QImode)") + (eq_attr "mode" "V1024QI,V1024BI") (symbol_ref "riscv_vector::get_vlmul(E_V1024QImode)") + (eq_attr "mode" "V2048QI,V2048BI") (symbol_ref "riscv_vector::get_vlmul(E_V2048QImode)") + (eq_attr "mode" "V4096QI,V4096BI") (symbol_ref "riscv_vector::get_vlmul(E_V4096QImode)") (eq_attr "mode" "V1HI") (symbol_ref "riscv_vector::get_vlmul(E_V1HImode)") (eq_attr "mode" "V2HI") (symbol_ref "riscv_vector::get_vlmul(E_V2HImode)") (eq_attr "mode" "V4HI") (symbol_ref "riscv_vector::get_vlmul(E_V4HImode)") @@ -607,19 +608,19 @@ (eq_attr "mode" "RVVM1x2DF") (const_int 64) ;; VLS modes. - (eq_attr "mode" "V1QI") (symbol_ref "riscv_vector::get_ratio(E_V1QImode)") - (eq_attr "mode" "V2QI") (symbol_ref "riscv_vector::get_ratio(E_V2QImode)") - (eq_attr "mode" "V4QI") (symbol_ref "riscv_vector::get_ratio(E_V4QImode)") - (eq_attr "mode" "V8QI") (symbol_ref "riscv_vector::get_ratio(E_V8QImode)") - (eq_attr "mode" "V16QI") (symbol_ref "riscv_vector::get_ratio(E_V16QImode)") - (eq_attr "mode" "V32QI") (symbol_ref "riscv_vector::get_ratio(E_V32QImode)") - (eq_attr "mode" "V64QI") (symbol_ref "riscv_vector::get_ratio(E_V64QImode)") - (eq_attr "mode" "V128QI") (symbol_ref "riscv_vector::get_ratio(E_V128QImode)") - (eq_attr "mode" "V256QI") (symbol_ref "riscv_vector::get_ratio(E_V256QImode)") - (eq_attr "mode" "V512QI") (symbol_ref "riscv_vector::get_ratio(E_V512QImode)") - (eq_attr "mode" "V1024QI") (symbol_ref "riscv_vector::get_ratio(E_V1024QImode)") - (eq_attr "mode" "V2048QI") (symbol_ref "riscv_vector::get_ratio(E_V2048QImode)") - (eq_attr "mode" "V4096QI") (symbol_ref "riscv_vector::get_ratio(E_V4096QImode)") + (eq_attr "mode" "V1QI,V1BI") (symbol_ref "riscv_vector::get_ratio(E_V1QImode)") + (eq_attr "mode" "V2QI,V2BI") (symbol_ref "riscv_vector::get_ratio(E_V2QImode)") + (eq_attr "mode" "V4QI,V4BI") (symbol_ref "riscv_vector::get_ratio(E_V4QImode)") + (eq_attr "mode" "V8QI,V8BI") (symbol_ref "riscv_vector::get_ratio(E_V8QImode)") + (eq_attr "mode" "V16QI,V16BI") (symbol_ref "riscv_vector::get_ratio(E_V16QImode)") + (eq_attr "mode" "V32QI,V32BI") (symbol_ref "riscv_vector::get_ratio(E_V32QImode)") + (eq_attr "mode" "V64QI,V64BI") (symbol_ref "riscv_vector::get_ratio(E_V64QImode)") + (eq_attr "mode" "V128QI,V128BI") (symbol_ref "riscv_vector::get_ratio(E_V128QImode)") + (eq_attr "mode" "V256QI,V256BI") (symbol_ref "riscv_vector::get_ratio(E_V256QImode)") + (eq_attr "mode" "V512QI,V512BI") (symbol_ref "riscv_vector::get_ratio(E_V512QImode)") + (eq_attr "mode" "V1024QI,V1024BI") (symbol_ref "riscv_vector::get_ratio(E_V1024QImode)") + (eq_attr "mode" "V2048QI,V2048BI") (symbol_ref "riscv_vector::get_ratio(E_V2048QImode)") + (eq_attr "mode" "V4096QI,V4096BI") (symbol_ref "riscv_vector::get_ratio(E_V4096QImode)") (eq_attr "mode" "V1HI") (symbol_ref "riscv_vector::get_ratio(E_V1HImode)") (eq_attr "mode" "V2HI") (symbol_ref "riscv_vector::get_ratio(E_V2HImode)") (eq_attr "mode" "V4HI") (symbol_ref "riscv_vector::get_ratio(E_V4HImode)") @@ -802,6 +803,7 @@ ;; The avl type value. (define_attr "avl_type" "" (cond [(eq_attr "mode" "V1QI,V2QI,V4QI,V8QI,V16QI,V32QI,V64QI,V128QI,V256QI,V512QI,V1024QI,V2048QI,V4096QI, + V1BI,V2BI,V4BI,V8BI,V16BI,V32BI,V64BI,V128BI,V256BI,V512BI,V1024BI,V2048BI,V4096BI, V1HI,V2HI,V4HI,V8HI,V16HI,V32HI,V64HI,V128HI,V256HI,V512HI,V1024HI,V2048HI, V1SI,V2SI,V4SI,V8SI,V16SI,V32SI,V64SI,V128SI,V256SI,V512SI,V1024SI, V1DI,V2DI,V4DI,V8DI,V16DI,V32DI,V64DI,V128DI,V256DI,V512DI, @@ -1540,16 +1542,16 @@ ;; constraint alternative 3 match vmclr.m. ;; constraint alternative 4 match vmset.m. (define_insn_and_split "@pred_mov<mode>" - [(set (match_operand:VB 0 "nonimmediate_operand" "=vr, m, vr, vr, vr") - (if_then_else:VB - (unspec:VB - [(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1, Wc1, Wc1, Wc1, Wc1") + [(set (match_operand:VB_VLS 0 "nonimmediate_operand" "=vr, m, vr, vr, vr") + (if_then_else:VB_VLS + (unspec:VB_VLS + [(match_operand:VB_VLS 1 "vector_all_trues_mask_operand" "Wc1, Wc1, Wc1, Wc1, Wc1") (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK") (match_operand 5 "const_int_operand" " i, i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:VB 3 "vector_move_operand" " m, vr, vr, Wc0, Wc1") - (match_operand:VB 2 "vector_undef_operand" " vu, vu, vu, vu, vu")))] + (match_operand:VB_VLS 3 "vector_move_operand" " m, vr, vr, Wc0, Wc1") + (match_operand:VB_VLS 2 "vector_undef_operand" " vu, vu, vu, vu, vu")))] "TARGET_VECTOR" "@ vlm.v\t%0,%3 @@ -1586,19 +1588,19 @@ (set_attr "vl_op_idx" "3")]) (define_insn "@pred_merge<mode>" - [(set (match_operand:V 0 "register_operand" "=vd,vd,vd,vd") - (if_then_else:V + [(set (match_operand:V_VLS 0 "register_operand" "=vd,vd,vd,vd") + (if_then_else:V_VLS (unspec:<VM> [(match_operand 5 "vector_length_operand" " rK,rK,rK,rK") (match_operand 6 "const_int_operand" " i, i, i, i") (match_operand 7 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (vec_merge:V - (match_operand:V 3 "vector_arith_operand" " vr,vr,vi,vi") - (match_operand:V 2 "register_operand" " vr,vr,vr,vr") + (vec_merge:V_VLS + (match_operand:V_VLS 3 "vector_arith_operand" " vr,vr,vi,vi") + (match_operand:V_VLS 2 "register_operand" " vr,vr,vr,vr") (match_operand:<VM> 4 "register_operand" " vm,vm,vm,vm")) - (match_operand:V 1 "vector_merge_operand" " vu, 0,vu, 0")))] + (match_operand:V_VLS 1 "vector_merge_operand" " vu, 0,vu, 0")))] "TARGET_VECTOR" "vmerge.v%o3m\t%0,%2,%v3,%4" [(set_attr "type" "vimerge") @@ -4202,8 +4204,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_ltge_operator" - [(match_operand:VI 4 "register_operand") - (match_operand:VI 5 "vector_arith_operand")]) + [(match_operand:V_VLSI 4 "register_operand") + (match_operand:V_VLSI 5 "vector_arith_operand")]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" {}) @@ -4219,8 +4221,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "comparison_except_ltge_operator" - [(match_operand:VI 3 "register_operand" " vr") - (match_operand:VI 4 "vector_arith_operand" "vrvi")]) + [(match_operand:V_VLSI 3 "register_operand" " vr") + (match_operand:V_VLSI 4 "vector_arith_operand" "vrvi")]) (match_dup 1)))] "TARGET_VECTOR" "vms%B2.v%o4\t%0,%3,%v4,v0.t" @@ -4243,10 +4245,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_ltge_operator" - [(match_operand:VI 4 "register_operand" " vr, vr, vr, vr") - (match_operand:VI 5 "vector_arith_operand" " vr, vr, vi, vi")]) + [(match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI 5 "vector_arith_operand" " vr, vr, vi, vi")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0, vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.v%o5\t%0,%4,%v5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4263,10 +4265,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_ltge_operator" - [(match_operand:VI 4 "register_operand" " vr, 0, vr, 0, 0, vr, 0, vr, vr") - (match_operand:VI 5 "vector_arith_operand" " vrvi, vrvi, 0, 0, vrvi, 0, 0, vrvi, vrvi")]) + [(match_operand:V_VLSI 4 "register_operand" " vr, 0, vr, 0, 0, vr, 0, vr, vr") + (match_operand:V_VLSI 5 "vector_arith_operand" " vrvi, vrvi, 0, 0, vrvi, 0, 0, vrvi, vrvi")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, vu, vu, 0, 0, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.v%o5\t%0,%4,%v5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4282,8 +4284,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "ltge_operator" - [(match_operand:VI 4 "register_operand") - (match_operand:VI 5 "vector_neg_arith_operand")]) + [(match_operand:V_VLSI 4 "register_operand") + (match_operand:V_VLSI 5 "vector_neg_arith_operand")]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" {}) @@ -4299,8 +4301,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "ltge_operator" - [(match_operand:VI 3 "register_operand" " vr") - (match_operand:VI 4 "vector_neg_arith_operand" "vrvj")]) + [(match_operand:V_VLSI 3 "register_operand" " vr") + (match_operand:V_VLSI 4 "vector_neg_arith_operand" "vrvj")]) (match_dup 1)))] "TARGET_VECTOR" "vms%B2.v%o4\t%0,%3,%v4,v0.t" @@ -4323,10 +4325,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "ltge_operator" - [(match_operand:VI 4 "register_operand" " vr, vr, vr, vr") - (match_operand:VI 5 "vector_neg_arith_operand" " vr, vr, vj, vj")]) + [(match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI 5 "vector_neg_arith_operand" " vr, vr, vj, vj")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0, vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.v%o5\t%0,%4,%v5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4343,10 +4345,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "ltge_operator" - [(match_operand:VI 4 "register_operand" " vr, 0, vr, 0, 0, vr, 0, vr, vr") - (match_operand:VI 5 "vector_neg_arith_operand" " vrvj, vrvj, 0, 0, vrvj, 0, 0, vrvj, vrvj")]) + [(match_operand:V_VLSI 4 "register_operand" " vr, 0, vr, 0, 0, vr, 0, vr, vr") + (match_operand:V_VLSI 5 "vector_neg_arith_operand" " vrvj, vrvj, 0, 0, vrvj, 0, 0, vrvj, vrvj")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, vu, vu, 0, 0, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.v%o5\t%0,%4,%v5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4362,8 +4364,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_QHS 4 "register_operand") - (vec_duplicate:VI_QHS + [(match_operand:V_VLSI_QHS 4 "register_operand") + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 5 "register_operand"))]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" @@ -4380,8 +4382,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "comparison_except_eqge_operator" - [(match_operand:VI_QHS 3 "register_operand" " vr") - (vec_duplicate:VI_QHS + [(match_operand:V_VLSI_QHS 3 "register_operand" " vr") + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 4 "register_operand" " r"))]) (match_dup 1)))] "TARGET_VECTOR" @@ -4405,11 +4407,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_QHS 4 "register_operand" " vr, vr") - (vec_duplicate:VI_QHS + [(match_operand:V_VLSI_QHS 4 "register_operand" " vr, vr") + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 5 "register_operand" " r, r"))]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4426,11 +4428,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_QHS 4 "register_operand" " vr, 0, 0, vr, vr") - (vec_duplicate:VI_QHS + [(match_operand:V_VLSI_QHS 4 "register_operand" " vr, 0, 0, vr, vr") + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 5 "register_operand" " r, r, r, r, r"))]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4446,9 +4448,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_QHS + [(vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 5 "register_operand")) - (match_operand:VI_QHS 4 "register_operand")]) + (match_operand:V_VLSI_QHS 4 "register_operand")]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" {}) @@ -4464,9 +4466,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "equality_operator" - [(vec_duplicate:VI_QHS + [(vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 4 "register_operand" " r")) - (match_operand:VI_QHS 3 "register_operand" " vr")]) + (match_operand:V_VLSI_QHS 3 "register_operand" " vr")]) (match_dup 1)))] "TARGET_VECTOR" "vms%B2.vx\t%0,%3,%4,v0.t" @@ -4489,11 +4491,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_QHS + [(vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 5 "register_operand" " r, r")) - (match_operand:VI_QHS 4 "register_operand" " vr, vr")]) + (match_operand:V_VLSI_QHS 4 "register_operand" " vr, vr")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4510,11 +4512,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_QHS + [(vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 5 "register_operand" " r, r, r, r, r")) - (match_operand:VI_QHS 4 "register_operand" " vr, 0, 0, vr, vr")]) + (match_operand:V_VLSI_QHS 4 "register_operand" " vr, 0, 0, vr, vr")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4532,8 +4534,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_D 4 "register_operand") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 4 "register_operand") + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 5 "reg_or_int_operand"))]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" @@ -4571,9 +4573,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (match_operand:<VEL> 5 "reg_or_int_operand")) - (match_operand:VI_D 4 "register_operand")]) + (match_operand:V_VLSI_D 4 "register_operand")]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" { @@ -4603,8 +4605,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "comparison_except_eqge_operator" - [(match_operand:VI_D 3 "register_operand" " vr") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 3 "register_operand" " vr") + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 4 "register_operand" " r"))]) (match_dup 1)))] "TARGET_VECTOR" @@ -4627,9 +4629,9 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (match_operand:<VEL> 4 "register_operand" " r")) - (match_operand:VI_D 3 "register_operand" " vr")]) + (match_operand:V_VLSI_D 3 "register_operand" " vr")]) (match_dup 1)))] "TARGET_VECTOR" "vms%B2.vx\t%0,%3,%4,v0.t" @@ -4652,11 +4654,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_D 4 "register_operand" " vr, vr") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 4 "register_operand" " vr, vr") + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 5 "register_operand" " r, r"))]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4673,11 +4675,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_D 4 "register_operand" " vr, 0, 0, vr, vr") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 4 "register_operand" " vr, 0, 0, vr, vr") + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 5 "register_operand" " r, r, r, r, r"))]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4694,11 +4696,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (match_operand:<VEL> 5 "register_operand" " r, r")) - (match_operand:VI_D 4 "register_operand" " vr, vr")]) + (match_operand:V_VLSI_D 4 "register_operand" " vr, vr")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4715,11 +4717,11 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (match_operand:<VEL> 5 "register_operand" " r, r, r, r, r")) - (match_operand:VI_D 4 "register_operand" " vr, 0, 0, vr, vr")]) + (match_operand:V_VLSI_D 4 "register_operand" " vr, 0, 0, vr, vr")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4735,8 +4737,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "comparison_except_eqge_operator" - [(match_operand:VI_D 3 "register_operand" " vr") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 3 "register_operand" " vr") + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 4 "register_operand" " r")))]) (match_dup 1)))] @@ -4761,12 +4763,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_D 4 "register_operand" " vr, vr") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 4 "register_operand" " vr, vr") + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 5 "register_operand" " r, r")))]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4782,12 +4784,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "comparison_except_eqge_operator" - [(match_operand:VI_D 4 "register_operand" " vr, 0, 0, vr, vr") - (vec_duplicate:VI_D + [(match_operand:V_VLSI_D 4 "register_operand" " vr, 0, 0, vr, vr") + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 5 "register_operand" " r, r, r, r, r")))]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4803,10 +4805,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 2 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 4 "register_operand" " r"))) - (match_operand:VI_D 3 "register_operand" " vr")]) + (match_operand:V_VLSI_D 3 "register_operand" " vr")]) (match_dup 1)))] "TARGET_VECTOR" "vms%B2.vx\t%0,%3,%4,v0.t" @@ -4829,12 +4831,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 5 "register_operand" " r, r"))) - (match_operand:VI_D 4 "register_operand" " vr, vr")]) + (match_operand:V_VLSI_D 4 "register_operand" " vr, vr")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, 0")))] - "TARGET_VECTOR && known_le (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_le_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4850,12 +4852,12 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "equality_operator" - [(vec_duplicate:VI_D + [(vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 5 "register_operand" " r, r, r, r, r"))) - (match_operand:VI_D 4 "register_operand" " vr, 0, 0, vr, vr")]) + (match_operand:V_VLSI_D 4 "register_operand" " vr, 0, 0, vr, vr")]) (match_operand:<VM> 2 "vector_merge_operand" " vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && known_gt (GET_MODE_SIZE (<MODE>mode), BYTES_PER_RISCV_VECTOR)" + "TARGET_VECTOR && riscv_vector::cmp_lmul_gt_one (<MODE>mode)" "vms%B3.vx\t%0,%4,%5%p1" [(set_attr "type" "vicmp") (set_attr "mode" "<MODE>")]) @@ -4884,8 +4886,8 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operator:<VM> 3 "ge_operator" - [(match_operand:VI 4 "register_operand") - (vec_duplicate:VI + [(match_operand:V_VLSI 4 "register_operand") + (vec_duplicate:V_VLSI (match_operand:<VEL> 5 "reg_or_int_operand"))]) (match_operand:<VM> 2 "vector_merge_operand")))] "TARGET_VECTOR" @@ -5846,18 +5848,18 @@ ;; For example, if we have vmxor.mm v1,v1,v1. It will be optmized as vmclr.m which ;; is generated by pred_mov. (define_insn "@pred_<optab><mode>" - [(set (match_operand:VB 0 "register_operand" "=vr") - (if_then_else:VB - (unspec:VB - [(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1") + [(set (match_operand:VB_VLS 0 "register_operand" "=vr") + (if_then_else:VB_VLS + (unspec:VB_VLS + [(match_operand:VB_VLS 1 "vector_all_trues_mask_operand" "Wc1") (match_operand 5 "vector_length_operand" " rK") (match_operand 6 "const_int_operand" " i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (any_bitwise:VB - (match_operand:VB 3 "register_operand" " vr") - (match_operand:VB 4 "register_operand" " vr")) - (match_operand:VB 2 "vector_undef_operand" " vu")))] + (any_bitwise:VB_VLS + (match_operand:VB_VLS 3 "register_operand" " vr") + (match_operand:VB_VLS 4 "register_operand" " vr")) + (match_operand:VB_VLS 2 "vector_undef_operand" " vu")))] "TARGET_VECTOR" "vm<insn>.mm\t%0,%3,%4" [(set_attr "type" "vmalu") @@ -5866,19 +5868,19 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))]) (define_insn "@pred_n<optab><mode>" - [(set (match_operand:VB 0 "register_operand" "=vr") - (if_then_else:VB - (unspec:VB - [(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1") + [(set (match_operand:VB_VLS 0 "register_operand" "=vr") + (if_then_else:VB_VLS + (unspec:VB_VLS + [(match_operand:VB_VLS 1 "vector_all_trues_mask_operand" "Wc1") (match_operand 5 "vector_length_operand" " rK") (match_operand 6 "const_int_operand" " i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (not:VB - (any_bitwise:VB - (match_operand:VB 3 "register_operand" " vr") - (match_operand:VB 4 "register_operand" " vr"))) - (match_operand:VB 2 "vector_undef_operand" " vu")))] + (not:VB_VLS + (any_bitwise:VB_VLS + (match_operand:VB_VLS 3 "register_operand" " vr") + (match_operand:VB_VLS 4 "register_operand" " vr"))) + (match_operand:VB_VLS 2 "vector_undef_operand" " vu")))] "TARGET_VECTOR" "vm<ninsn>.mm\t%0,%3,%4" [(set_attr "type" "vmalu") @@ -5887,19 +5889,19 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))]) (define_insn "@pred_<optab>not<mode>" - [(set (match_operand:VB 0 "register_operand" "=vr") - (if_then_else:VB - (unspec:VB - [(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1") + [(set (match_operand:VB_VLS 0 "register_operand" "=vr") + (if_then_else:VB_VLS + (unspec:VB_VLS + [(match_operand:VB_VLS 1 "vector_all_trues_mask_operand" "Wc1") (match_operand 5 "vector_length_operand" " rK") (match_operand 6 "const_int_operand" " i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (and_ior:VB - (match_operand:VB 3 "register_operand" " vr") - (not:VB - (match_operand:VB 4 "register_operand" " vr"))) - (match_operand:VB 2 "vector_undef_operand" " vu")))] + (and_ior:VB_VLS + (match_operand:VB_VLS 3 "register_operand" " vr") + (not:VB_VLS + (match_operand:VB_VLS 4 "register_operand" " vr"))) + (match_operand:VB_VLS 2 "vector_undef_operand" " vu")))] "TARGET_VECTOR" "vm<insn>n.mm\t%0,%3,%4" [(set_attr "type" "vmalu") @@ -5908,17 +5910,17 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))]) (define_insn "@pred_not<mode>" - [(set (match_operand:VB 0 "register_operand" "=vr") - (if_then_else:VB - (unspec:VB - [(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1") + [(set (match_operand:VB_VLS 0 "register_operand" "=vr") + (if_then_else:VB_VLS + (unspec:VB_VLS + [(match_operand:VB_VLS 1 "vector_all_trues_mask_operand" "Wc1") (match_operand 4 "vector_length_operand" " rK") (match_operand 5 "const_int_operand" " i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (not:VB - (match_operand:VB 3 "register_operand" " vr")) - (match_operand:VB 2 "vector_undef_operand" " vu")))] + (not:VB_VLS + (match_operand:VB_VLS 3 "register_operand" " vr")) + (match_operand:VB_VLS 2 "vector_undef_operand" " vu")))] "TARGET_VECTOR" "vmnot.m\t%0,%3" [(set_attr "type" "vmalu") @@ -8184,8 +8186,8 @@ ;; vslide instructions (define_insn "@pred_slide<ud><mode>" - [(set (match_operand:V 0 "register_operand" "<ud_constraint>") - (unspec:V + [(set (match_operand:V_VLS 0 "register_operand" "<ud_constraint>") + (unspec:V_VLS [(unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -8194,8 +8196,8 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:V 2 "vector_merge_operand" " vu, 0, vu, 0") - (match_operand:V 3 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLS 2 "vector_merge_operand" " vu, 0, vu, 0") + (match_operand:V_VLS 3 "register_operand" " vr, vr, vr, vr") (match_operand 4 "pmode_reg_or_uimm5_operand" " rK, rK, rK, rK")] VSLIDES))] "TARGET_VECTOR" "vslide<ud>.v%o4\t%0,%3,%4%p1" @@ -8204,8 +8206,8 @@ ;; vslide1 instructions (define_insn "@pred_slide<ud><mode>" - [(set (match_operand:VI_QHS 0 "register_operand" "<ud_constraint>") - (unspec:VI_QHS + [(set (match_operand:V_VLSI_QHS 0 "register_operand" "<ud_constraint>") + (unspec:V_VLSI_QHS [(unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -8214,8 +8216,8 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:VI_QHS 2 "vector_merge_operand" " vu, 0, vu, 0") - (match_operand:VI_QHS 3 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI_QHS 2 "vector_merge_operand" " vu, 0, vu, 0") + (match_operand:V_VLSI_QHS 3 "register_operand" " vr, vr, vr, vr") (match_operand:<VEL> 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ")] VSLIDES1))] "TARGET_VECTOR" "vslide<ud>.vx\t%0,%3,%z4%p1" @@ -8223,8 +8225,8 @@ (set_attr "mode" "<MODE>")]) (define_expand "@pred_slide<ud><mode>" - [(set (match_operand:VI_D 0 "register_operand") - (unspec:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand") + (unspec:V_VLSI_D [(unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 5 "reg_or_int_operand") @@ -8233,8 +8235,8 @@ (match_operand 8 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:VI_D 2 "vector_merge_operand") - (match_operand:VI_D 3 "register_operand") + (match_operand:V_VLSI_D 2 "vector_merge_operand") + (match_operand:V_VLSI_D 3 "register_operand") (match_operand:<VEL> 4 "reg_or_int_operand")] VSLIDES1))] "TARGET_VECTOR" { @@ -8245,8 +8247,8 @@ }) (define_insn "*pred_slide<ud><mode>" - [(set (match_operand:VI_D 0 "register_operand" "<ud_constraint>") - (unspec:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "<ud_constraint>") + (unspec:V_VLSI_D [(unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -8255,8 +8257,8 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:VI_D 2 "vector_merge_operand" " vu, 0, vu, 0") - (match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, 0, vu, 0") + (match_operand:V_VLSI_D 3 "register_operand" " vr, vr, vr, vr") (match_operand:<VEL> 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ")] VSLIDES1))] "TARGET_VECTOR" "vslide<ud>.vx\t%0,%3,%z4%p1" @@ -8264,8 +8266,8 @@ (set_attr "mode" "<MODE>")]) (define_insn "*pred_slide<ud><mode>_extended" - [(set (match_operand:VI_D 0 "register_operand" "<ud_constraint>") - (unspec:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "<ud_constraint>") + (unspec:V_VLSI_D [(unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -8274,8 +8276,8 @@ (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:VI_D 2 "vector_merge_operand" " vu, 0, vu, 0") - (match_operand:VI_D 3 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, 0, vu, 0") + (match_operand:V_VLSI_D 3 "register_operand" " vr, vr, vr, vr") (sign_extend:<VEL> (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ, rJ, rJ, rJ"))] VSLIDES1))] "TARGET_VECTOR" @@ -8305,8 +8307,8 @@ ;; vrgather (define_insn "@pred_gather<mode>" - [(set (match_operand:V 0 "register_operand" "=&vr, &vr") - (if_then_else:V + [(set (match_operand:V_VLS 0 "register_operand" "=&vr, &vr") + (if_then_else:V_VLS (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1") (match_operand 5 "vector_length_operand" " rK, rK") @@ -8315,18 +8317,18 @@ (match_operand 8 "const_int_operand" " i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (unspec:V - [(match_operand:V 3 "register_operand" " vr, vr") + (unspec:V_VLS + [(match_operand:V_VLS 3 "register_operand" " vr, vr") (match_operand:<VINDEX> 4 "register_operand" " vr, vr")] UNSPEC_VRGATHER) - (match_operand:V 2 "vector_merge_operand" " vu, 0")))] + (match_operand:V_VLS 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" "vrgather.vv\t%0,%3,%4%p1" [(set_attr "type" "vgather") (set_attr "mode" "<MODE>")]) (define_insn "@pred_gather<mode>_scalar" - [(set (match_operand:V 0 "register_operand" "=&vr, &vr") - (if_then_else:V + [(set (match_operand:V_VLS 0 "register_operand" "=&vr, &vr") + (if_then_else:V_VLS (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1") (match_operand 5 "vector_length_operand" " rK, rK") @@ -8335,10 +8337,10 @@ (match_operand 8 "const_int_operand" " i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (unspec:V - [(match_operand:V 3 "register_operand" " vr, vr") + (unspec:V_VLS + [(match_operand:V_VLS 3 "register_operand" " vr, vr") (match_operand 4 "pmode_reg_or_uimm5_operand" " rK, rK")] UNSPEC_VRGATHER) - (match_operand:V 2 "vector_merge_operand" " vu, 0")))] + (match_operand:V_VLS 2 "vector_merge_operand" " vu, 0")))] "TARGET_VECTOR" "vrgather.v%o4\t%0,%3,%4%p1" [(set_attr "type" "vgather") @@ -8367,8 +8369,8 @@ ;; vcompress (define_insn "@pred_compress<mode>" - [(set (match_operand:V 0 "register_operand" "=&vr, &vr") - (unspec:V + [(set (match_operand:V_VLS 0 "register_operand" "=&vr, &vr") + (unspec:V_VLS [(unspec:<VM> [(match_operand:<VM> 3 "register_operand" " vm, vm") (match_operand 4 "vector_length_operand" " rK, rK") @@ -8376,8 +8378,8 @@ (match_operand 6 "const_int_operand" " i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:V 2 "register_operand" " vr, vr") - (match_operand:V 1 "vector_merge_operand" " vu, 0")] UNSPEC_VCOMPRESS))] + (match_operand:V_VLS 2 "register_operand" " vr, vr") + (match_operand:V_VLS 1 "vector_merge_operand" " vu, 0")] UNSPEC_VCOMPRESS))] "TARGET_VECTOR" "vcompress.vm\t%0,%2,%3" [(set_attr "type" "vcompress") diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c2dcca1..4879a01 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2023-09-08 Patrick Palka <ppalka@redhat.com> + + PR c++/99599 + * pt.cc (check_non_deducible_conversions): Add bool parameter + passed down to check_non_deducible_conversion. + (fn_type_unification): Call check_non_deducible_conversions + an extra time before satisfaction with noninst_only_p=true. + (conversion_may_instantiate_p): Define. + (check_non_deducible_conversion): Add bool parameter controlling + whether to compute only conversions that are guaranteed to + not induce template instantiation. + +2023-09-07 Sandra Loosemore <sandra@codesourcery.com> + + PR c++/111274 + * parser.cc (fixup_blocks_walker): Check for null BIND_EXPR_BLOCK. + 2023-09-06 Jason Merrill <jason@redhat.com> * class.cc (check_subobject_offset): Check diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index ed0675c..8808da3 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -44490,7 +44490,10 @@ fixup_blocks_walker (tree *tp, int *walk_subtrees, void *dp) { tree superblock = *(tree *)dp; - if (TREE_CODE (*tp) == BIND_EXPR) + /* BIND_EXPR_BLOCK may be null if the expression is not a + full-expression; if there's no block, no patching is necessary + for this node. */ + if (TREE_CODE (*tp) == BIND_EXPR && BIND_EXPR_BLOCK (*tp)) { tree block = BIND_EXPR_BLOCK (*tp); if (superblock) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 0790bbf..838179d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -151,7 +151,7 @@ static tree get_partial_spec_bindings (tree, tree, tree); static void tsubst_enum (tree, tree, tree); static bool check_instantiated_args (tree, tree, tsubst_flags_t); static int check_non_deducible_conversion (tree, tree, unification_kind_t, int, - struct conversion **, bool); + struct conversion **, bool, bool); static int maybe_adjust_types_for_deduction (tree, unification_kind_t, tree*, tree*, tree); static int type_unification_real (tree, tree, tree, const tree *, @@ -22321,7 +22321,8 @@ pack_deducible_p (tree parm, tree fn) static int check_non_deducible_conversions (tree parms, const tree *args, unsigned nargs, tree fn, unification_kind_t strict, int flags, - struct conversion **convs, bool explain_p) + struct conversion **convs, bool explain_p, + bool noninst_only_p) { /* Non-constructor methods need to leave a conversion for 'this', which isn't included in nargs here. */ @@ -22357,7 +22358,7 @@ check_non_deducible_conversions (tree parms, const tree *args, unsigned nargs, int lflags = conv_flags (ia, nargs, fn, arg, flags); if (check_non_deducible_conversion (parm, arg, strict, lflags, - conv_p, explain_p)) + conv_p, explain_p, noninst_only_p)) return 1; } @@ -22657,6 +22658,16 @@ fn_type_unification (tree fn, deduced: + /* As a refinement of CWG2369, check first and foremost non-dependent + conversions that we know are not going to induce template instantiation + (PR99599). */ + if (strict == DEDUCE_CALL + && incomplete + && check_non_deducible_conversions (parms, args, nargs, fn, strict, flags, + convs, explain_p, + /*noninst_only_p=*/true)) + goto fail; + /* CWG2369: Check satisfaction before non-deducible conversions. */ if (!constraints_satisfied_p (fn, targs)) { @@ -22670,7 +22681,8 @@ fn_type_unification (tree fn, as the standard says that we substitute explicit args immediately. */ if (incomplete && check_non_deducible_conversions (parms, args, nargs, fn, strict, flags, - convs, explain_p)) + convs, explain_p, + /*noninst_only_p=*/false)) goto fail; /* All is well so far. Now, check: @@ -22897,6 +22909,59 @@ maybe_adjust_types_for_deduction (tree tparms, return result; } +/* Return true if computing a conversion from FROM to TO might induce template + instantiation. Conversely, if this predicate returns false then computing + the conversion definitely won't induce template instantiation. */ + +static bool +conversion_may_instantiate_p (tree to, tree from) +{ + to = non_reference (to); + from = non_reference (from); + + bool ptr_conv_p = false; + if (TYPE_PTR_P (to) + && TYPE_PTR_P (from)) + { + to = TREE_TYPE (to); + from = TREE_TYPE (from); + ptr_conv_p = true; + } + + /* If one of the types is a not-yet-instantiated class template + specialization, then computing the conversion might instantiate + it in order to inspect bases, conversion functions and/or + converting constructors. */ + if ((CLASS_TYPE_P (to) + && !COMPLETE_TYPE_P (to) + && CLASSTYPE_TEMPLATE_INSTANTIATION (to)) + || (CLASS_TYPE_P (from) + && !COMPLETE_TYPE_P (from) + && CLASSTYPE_TEMPLATE_INSTANTIATION (from))) + return true; + + /* Converting from one pointer type to another, or between + reference-related types, always yields a standard conversion. */ + if (ptr_conv_p || reference_related_p (to, from)) + return false; + + /* Converting to a non-aggregate class type will consider its + user-declared constructors, which might induce instantiation. */ + if (CLASS_TYPE_P (to) + && CLASSTYPE_NON_AGGREGATE (to)) + return true; + + /* Similarly, converting from a class type will consider its conversion + functions. */ + if (CLASS_TYPE_P (from) + && TYPE_HAS_CONVERSION (from)) + return true; + + /* Otherwise, computing this conversion definitely won't induce + template instantiation. */ + return false; +} + /* Subroutine of fn_type_unification. PARM is a function parameter of a template which doesn't contain any deducible template parameters; check if ARG is a suitable match for it. STRICT, FLAGS and EXPLAIN_P are as in @@ -22905,7 +22970,7 @@ maybe_adjust_types_for_deduction (tree tparms, static int check_non_deducible_conversion (tree parm, tree arg, unification_kind_t strict, int flags, struct conversion **conv_p, - bool explain_p) + bool explain_p, bool noninst_only_p) { tree type; @@ -22925,6 +22990,18 @@ check_non_deducible_conversion (tree parm, tree arg, unification_kind_t strict, } else if (strict == DEDUCE_CALL) { + if (conv_p && *conv_p) + { + /* This conversion was already computed earlier (when + computing only non-instantiating conversions). */ + gcc_checking_assert (!noninst_only_p); + return unify_success (explain_p); + } + + if (noninst_only_p + && conversion_may_instantiate_p (parm, type)) + return unify_success (explain_p); + bool ok = false; tree conv_arg = TYPE_P (arg) ? NULL_TREE : arg; if (conv_p) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 1da498a..d19b466 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -1213,6 +1213,25 @@ wide_int_binop (wide_int &res, return true; } +/* Returns true if we know who is smaller or equal, ARG1 or ARG2, and set the + min value to RES. */ +bool +can_min_p (const_tree arg1, const_tree arg2, poly_wide_int &res) +{ + if (known_le (wi::to_poly_widest (arg1), wi::to_poly_widest (arg2))) + { + res = wi::to_poly_wide (arg1); + return true; + } + else if (known_le (wi::to_poly_widest (arg2), wi::to_poly_widest (arg1))) + { + res = wi::to_poly_wide (arg2); + return true; + } + + return false; +} + /* Combine two poly int's ARG1 and ARG2 under operation CODE to produce a new constant in RES. Return FALSE if we don't know how to evaluate CODE at compile-time. */ @@ -1261,6 +1280,11 @@ poly_int_binop (poly_wide_int &res, enum tree_code code, return false; break; + case MIN_EXPR: + if (!can_min_p (arg1, arg2, res)) + return false; + break; + default: return false; } diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 37ab771..76ea9ba 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,14 @@ +2023-09-09 Mikael Morin <mikael@gcc.gnu.org> + + * bbt.cc (delete_treap): Add argument REMOVED, set it to the removed + element from the tree. Change NULL to nullptr. + (gfc_delete_bbt): Return the removed element from the tree. + * gfortran.h (gfc_delete_symtree): Remove prototype. + (gfc_delete_bbt): Set return type to pointer. + * symbol.cc (gfc_delete_symtree): Make static. Get the element to be + freed from the result of gfc_delete_bbt. Remove the preliminary walk to + get it. + 2023-09-01 Harald Anlauf <anlauf@gmx.de> PR fortran/31059 diff --git a/gcc/fortran/bbt.cc b/gcc/fortran/bbt.cc index 851e5e9..7f1f406 100644 --- a/gcc/fortran/bbt.cc +++ b/gcc/fortran/bbt.cc @@ -162,37 +162,54 @@ delete_root (gfc_bbt *t) } -/* Delete an element from a tree. The 'old' value does not - necessarily have to point to the element to be deleted, it must - just point to a treap structure with the key to be deleted. - Returns the new root node of the tree. */ +/* Delete an element from a tree, returning the new root node of the tree. + The OLD value does not necessarily have to point to the element to be + deleted, it must just point to a treap structure with the key to be deleted. + The REMOVED argument, if non-null, is set to the removed element from the + tree upon return. */ static gfc_bbt * -delete_treap (gfc_bbt *old, gfc_bbt *t, compare_fn compare) +delete_treap (gfc_bbt *old, gfc_bbt *t, compare_fn compare, gfc_bbt **removed) { int c; - if (t == NULL) - return NULL; + if (t == nullptr) + { + if (removed) + *removed = nullptr; + return nullptr; + } c = (*compare) (old, t); if (c < 0) - t->left = delete_treap (old, t->left, compare); + t->left = delete_treap (old, t->left, compare, removed); if (c > 0) - t->right = delete_treap (old, t->right, compare); + t->right = delete_treap (old, t->right, compare, removed); if (c == 0) - t = delete_root (t); + { + if (removed) + *removed = t; + t = delete_root (t); + } return t; } -void +/* Delete the element from the tree at *ROOT that matches the OLD element + according to the COMPARE_FN function. This updates the *ROOT pointer to + point to the new tree root (if different from the original) and returns the + deleted element. */ + +void * gfc_delete_bbt (void *root, void *old, compare_fn compare) { gfc_bbt **t; + gfc_bbt *removed; t = (gfc_bbt **) root; - *t = delete_treap ((gfc_bbt *) old, *t, compare); + *t = delete_treap ((gfc_bbt *) old, *t, compare, &removed); + + return (void *) removed; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index b37c6bb..371f874 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3510,7 +3510,6 @@ bool gfc_reference_st_label (gfc_st_label *, gfc_sl_type); gfc_namespace *gfc_get_namespace (gfc_namespace *, int); gfc_symtree *gfc_new_symtree (gfc_symtree **, const char *); gfc_symtree *gfc_find_symtree (gfc_symtree *, const char *); -void gfc_delete_symtree (gfc_symtree **, const char *); gfc_symtree *gfc_get_unique_symtree (gfc_namespace *); gfc_user_op *gfc_get_uop (const char *); gfc_user_op *gfc_find_uop (const char *, gfc_namespace *); @@ -3911,7 +3910,7 @@ bool gfc_inline_intrinsic_function_p (gfc_expr *); /* bbt.cc */ typedef int (*compare_fn) (void *, void *); void gfc_insert_bbt (void *, void *, compare_fn); -void gfc_delete_bbt (void *, void *, compare_fn); +void * gfc_delete_bbt (void *, void *, compare_fn); /* dump-parse-tree.cc */ void gfc_dump_parse_tree (gfc_namespace *, FILE *); diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc index aa3cdc9..2cba2ea 100644 --- a/gcc/fortran/symbol.cc +++ b/gcc/fortran/symbol.cc @@ -2948,7 +2948,7 @@ gfc_new_symtree (gfc_symtree **root, const char *name) /* Delete a symbol from the tree. Does not free the symbol itself! */ -void +static void gfc_delete_symtree (gfc_symtree **root, const char *name) { gfc_symtree st, *st0; @@ -2963,10 +2963,8 @@ gfc_delete_symtree (gfc_symtree **root, const char *name) else p = name; - st0 = gfc_find_symtree (*root, p); - st.name = gfc_get_string ("%s", p); - gfc_delete_bbt (root, &st, compare_symtree); + st0 = (gfc_symtree *) gfc_delete_bbt (root, &st, compare_symtree); free (st0); } diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 01173c5..13c3308 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -351,10 +351,14 @@ gimple_ranger::prefill_name (vrange &r, tree name) if (!gimple_range_op_handler::supported_p (stmt) && !is_a<gphi *> (stmt)) return; - bool current; // If this op has not been processed yet, then push it on the stack - if (!m_cache.get_global_range (r, name, current)) - m_stmt_list.safe_push (name); + if (!m_cache.get_global_range (r, name)) + { + bool current; + // Set the global cache value and mark as alway_current. + m_cache.get_global_range (r, name, current); + m_stmt_list.safe_push (name); + } } // This routine will seed the global cache with most of the dependencies of diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index c718bed..3aaa490 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -1462,6 +1462,9 @@ static int goal_alt_matches[MAX_RECOG_OPERANDS]; static int goal_alt_dont_inherit_ops_num; /* Numbers of operands whose reload pseudos should not be inherited. */ static int goal_alt_dont_inherit_ops[MAX_RECOG_OPERANDS]; +/* True if we should try only this alternative for the next constraint sub-pass + to speed up the sub-pass. */ +static bool goal_reuse_alt_p; /* True if the insn commutative operands should be swapped. */ static bool goal_alt_swapped; /* The chosen insn alternative. */ @@ -2130,6 +2133,7 @@ process_alt_operands (int only_alternative) int curr_alt_dont_inherit_ops_num; /* Numbers of operands whose reload pseudos should not be inherited. */ int curr_alt_dont_inherit_ops[MAX_RECOG_OPERANDS]; + bool curr_reuse_alt_p; /* True if output stack pointer reload should be generated for the current alternative. */ bool curr_alt_out_sp_reload_p; @@ -2217,6 +2221,7 @@ process_alt_operands (int only_alternative) reject += static_reject; early_clobbered_regs_num = 0; curr_alt_out_sp_reload_p = false; + curr_reuse_alt_p = true; for (nop = 0; nop < n_operands; nop++) { @@ -2574,7 +2579,10 @@ process_alt_operands (int only_alternative) if (satisfies_memory_constraint_p (op, cn)) win = true; else if (spilled_pseudo_p (op)) - win = true; + { + curr_reuse_alt_p = false; + win = true; + } break; } break; @@ -3318,6 +3326,7 @@ process_alt_operands (int only_alternative) goal_alt_offmemok[nop] = curr_alt_offmemok[nop]; } goal_alt_dont_inherit_ops_num = curr_alt_dont_inherit_ops_num; + goal_reuse_alt_p = curr_reuse_alt_p; for (nop = 0; nop < curr_alt_dont_inherit_ops_num; nop++) goal_alt_dont_inherit_ops[nop] = curr_alt_dont_inherit_ops[nop]; goal_alt_swapped = curr_swapped; @@ -4399,7 +4408,8 @@ curr_insn_transform (bool check_only_p) } lra_assert (goal_alt_number >= 0); - lra_set_used_insn_alternative (curr_insn, goal_alt_number); + lra_set_used_insn_alternative (curr_insn, goal_reuse_alt_p + ? goal_alt_number : LRA_UNKNOWN_ALT); if (lra_dump_file != NULL) { diff --git a/gcc/match.pd b/gcc/match.pd index 8c24dae..209b059 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3942,7 +3942,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for minmax (min min max max ) cmp (ge lt le gt ) (simplify - (cmp @0 (minmax:c @0 @1)) + (cmp:c @0 (minmax:c @0 @1)) { constant_boolean_node (cmp == GE_EXPR || cmp == LE_EXPR, type); } )) /* Undo fancy ways of writing max/min or other ?: expressions, like @@ -5431,18 +5431,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for cmp (gt ge lt le) minmax (min min max max) (simplify - (cond (cmp @0 @1) (minmax:c@2 @0 @3) @4) + (cond (cmp:c @0 @1) (minmax:c@2 @0 @3) @4) (with { tree_code code = minmax_from_comparison (cmp, @0, @1, @0, @4); } (if ((cmp == LT_EXPR || cmp == LE_EXPR) && code == MIN_EXPR - && integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, @3, @1))) + && integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, @3, @4))) (min @2 @4) (if ((cmp == GT_EXPR || cmp == GE_EXPR) && code == MAX_EXPR - && integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, @3, @1))) + && integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, @3, @4))) (max @2 @4)))))) #if GIMPLE diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h index 6eb99b1..0d9bc99 100644 --- a/gcc/pretty-print.h +++ b/gcc/pretty-print.h @@ -333,28 +333,6 @@ pp_get_prefix (const pretty_printer *pp) { return pp->prefix; } #define pp_decimal_int(PP, I) pp_scalar (PP, "%d", I) #define pp_unsigned_wide_integer(PP, I) \ pp_scalar (PP, HOST_WIDE_INT_PRINT_UNSIGNED, (unsigned HOST_WIDE_INT) I) -#define pp_wide_int(PP, W, SGN) \ - do \ - { \ - const wide_int_ref &pp_wide_int_ref = (W); \ - unsigned int pp_wide_int_prec \ - = pp_wide_int_ref.get_precision (); \ - if ((pp_wide_int_prec + 3) / 4 \ - > sizeof (pp_buffer (PP)->digit_buffer) - 3) \ - { \ - char *pp_wide_int_buf \ - = XALLOCAVEC (char, (pp_wide_int_prec + 3) / 4 + 3);\ - print_dec (pp_wide_int_ref, pp_wide_int_buf, SGN); \ - pp_string (PP, pp_wide_int_buf); \ - } \ - else \ - { \ - print_dec (pp_wide_int_ref, \ - pp_buffer (PP)->digit_buffer, SGN); \ - pp_string (PP, pp_buffer (PP)->digit_buffer); \ - } \ - } \ - while (0) #define pp_vrange(PP, R) \ do \ { \ @@ -453,6 +431,19 @@ pp_wide_integer (pretty_printer *pp, HOST_WIDE_INT i) pp_scalar (pp, HOST_WIDE_INT_PRINT_DEC, i); } +inline void +pp_wide_int (pretty_printer *pp, const wide_int_ref &w, signop sgn) +{ + unsigned int prec = w.get_precision (); + if (UNLIKELY ((prec + 3) / 4 > sizeof (pp_buffer (pp)->digit_buffer) - 3)) + pp_wide_int_large (pp, w, sgn); + else + { + print_dec (w, pp_buffer (pp)->digit_buffer, sgn); + pp_string (pp, pp_buffer (pp)->digit_buffer); + } +} + template<unsigned int N, typename T> void pp_wide_integer (pretty_printer *pp, const poly_int_pod<N, T> &); diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index eebc73f99..cc729e1 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -783,7 +783,7 @@ operator_equal::op1_op2_relation (const irange &lhs, const frange &, return VREL_NE; // TRUE = op1 == op2 indicates EQ_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_EQ; return VREL_VARYING; } @@ -915,7 +915,7 @@ operator_not_equal::op1_op2_relation (const irange &lhs, const frange &, return VREL_EQ; // TRUE = op1 != op2 indicates NE_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_NE; return VREL_VARYING; } @@ -1037,7 +1037,7 @@ operator_lt::op1_op2_relation (const irange &lhs, const frange &, return VREL_GE; // TRUE = op1 < op2 indicates LT_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_LT; return VREL_VARYING; } @@ -1144,7 +1144,7 @@ operator_le::op1_op2_relation (const irange &lhs, const frange &, return VREL_GT; // TRUE = op1 <= op2 indicates LE_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_LE; return VREL_VARYING; } @@ -2206,21 +2206,6 @@ public: const frange &op1, const frange &op2, relation_trio trio = TRIO_VARYING) const final override { - relation_kind rel = trio.op1_op2 (); - - // VREL_EQ is really VREL_(UN)EQ because we could have a NAN in - // the operands, but since LTGT_EXPR is really a NE_EXPR without - // the NAN, VREL_EQ & LTGT_EXPR is an impossibility. - if (rel == VREL_EQ) - { - r = range_false (type); - return true; - } - // ...otherwise pretend we're trying to resolve a NE_EXPR and - // everything will "just work". - if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE)) - return true; - if (op1.known_isnan () || op2.known_isnan ()) { r = range_false (type); diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 619979f..33b193b 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -915,7 +915,7 @@ operator_equal::op1_op2_relation (const irange &lhs, const irange &, return VREL_NE; // TRUE = op1 == op2 indicates EQ_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_EQ; return VREL_VARYING; } @@ -1017,7 +1017,7 @@ operator_not_equal::op1_op2_relation (const irange &lhs, const irange &, return VREL_EQ; // TRUE = op1 != op2 indicates NE_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_NE; return VREL_VARYING; } @@ -1178,7 +1178,7 @@ operator_lt::op1_op2_relation (const irange &lhs, const irange &, return VREL_GE; // TRUE = op1 < op2 indicates LT_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_LT; return VREL_VARYING; } @@ -1279,7 +1279,7 @@ operator_le::op1_op2_relation (const irange &lhs, const irange &, return VREL_GT; // TRUE = op1 <= op2 indicates LE_EXPR. - if (lhs.undefined_p () || !contains_zero_p (lhs)) + if (!contains_zero_p (lhs)) return VREL_LE; return VREL_VARYING; } @@ -2957,7 +2957,7 @@ operator_cast::op1_range (irange &r, tree type, { // If the LHS is not a pointer nor a singleton, then it is // either VARYING or non-zero. - if (!contains_zero_p (lhs)) + if (!lhs.undefined_p () && !contains_zero_p (lhs)) r.set_nonzero (type); else r.set_varying (type); @@ -3368,10 +3368,10 @@ operator_bitwise_and::wi_fold (irange &r, tree type, static void set_nonzero_range_from_mask (irange &r, tree type, const irange &lhs) { - if (!contains_zero_p (lhs)) - r = range_nonzero (type); - else + if (lhs.undefined_p () || contains_zero_p (lhs)) r.set_varying (type); + else + r.set_nonzero (type); } /* Find out smallest RES where RES > VAL && (RES & MASK) == RES, if any @@ -3798,7 +3798,7 @@ operator_bitwise_xor::op1_range (irange &r, tree type, else if (op2.zero_p ()) r = range_true (type); // See get_bool_state for the rationale - else if (contains_zero_p (op2)) + else if (op2.undefined_p () || contains_zero_p (op2)) r = range_true_and_false (type); else r = range_false (type); @@ -4335,10 +4335,10 @@ operator_addr_expr::fold_range (irange &r, tree type, // Return a non-null pointer of the LHS type (passed in op2). if (lh.zero_p ()) r = range_zero (type); - else if (!contains_zero_p (lh)) - r = range_nonzero (type); - else + else if (lh.undefined_p () || contains_zero_p (lh)) r.set_varying (type); + else + r.set_nonzero (type); return true; } @@ -4348,14 +4348,14 @@ operator_addr_expr::op1_range (irange &r, tree type, const irange &op2, relation_trio) const { - if (empty_range_varying (r, type, lhs, op2)) + if (empty_range_varying (r, type, lhs, op2)) return true; // Return a non-null pointer of the LHS type (passed in op2), but only // if we cant overflow, eitherwise a no-zero offset could wrap to zero. // See PR 111009. - if (!contains_zero_p (lhs) && TYPE_OVERFLOW_UNDEFINED (type)) - r = range_nonzero (type); + if (!lhs.undefined_p () && !contains_zero_p (lhs) && TYPE_OVERFLOW_UNDEFINED (type)) + r.set_nonzero (type); else r.set_varying (type); return true; diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog index de25e73..31a6ede 100644 --- a/gcc/rust/ChangeLog +++ b/gcc/rust/ChangeLog @@ -1,3 +1,14 @@ +2023-09-07 David Malcolm <dmalcolm@redhat.com> + + * rust-diagnostics.cc (rust_error_at): New overload. + * rust-diagnostics.h (struct ErrorCode): New struct. + (rust_error_at): New. + (rust_be_error_at): Likewise. + * rust-gcc-diagnostics.cc (class rust_error_code_rule): New class. + (rust_be_error_at): New function. + * typecheck/rust-casts.cc (TypeCastRules::emit_cast_error): Emit E0054 + when reporting invalid cast error. + 2023-07-05 Robin Dapp <rdapp@ventanamicro.com> Juzhe-Zhong <juzhe.zhong@rivai.ai> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2251e6f..96520fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,409 @@ +2023-09-10 Andrew Pinski <apinski@marvell.com> + + PR tree-optimization/111331 + * gcc.c-torture/execute/pr111331-1.c: New test. + * gcc.c-torture/execute/pr111331-2.c: New test. + * gcc.c-torture/execute/pr111331-3.c: New test. + +2023-09-09 benjamin priour <vultkayn@gcc.gnu.org> + + PR analyzer/96395 + * gcc.dg/analyzer/allocation-size-1.c: Moved to... + * c-c++-common/analyzer/allocation-size-1.c: ...here. + * gcc.dg/analyzer/allocation-size-2.c: Moved to... + * c-c++-common/analyzer/allocation-size-2.c: ...here. + * gcc.dg/analyzer/allocation-size-3.c: Moved to... + * c-c++-common/analyzer/allocation-size-3.c: ...here. + * gcc.dg/analyzer/allocation-size-4.c: Moved to... + * c-c++-common/analyzer/allocation-size-4.c: ...here. + * gcc.dg/analyzer/analyzer-verbosity-0.c: Moved to... + * c-c++-common/analyzer/analyzer-verbosity-0.c: ...here. + * gcc.dg/analyzer/analyzer-verbosity-1.c: Moved to... + * c-c++-common/analyzer/analyzer-verbosity-1.c: ...here. + * gcc.dg/analyzer/analyzer-verbosity-2.c: Moved to... + * c-c++-common/analyzer/analyzer-verbosity-2.c: ...here. + * gcc.dg/analyzer/analyzer-verbosity-3.c: Moved to... + * c-c++-common/analyzer/analyzer-verbosity-3.c: ...here. + * gcc.dg/analyzer/attr-alloc_size-1.c: Moved to... + * c-c++-common/analyzer/attr-alloc_size-1.c: ...here. + * gcc.dg/analyzer/attr-alloc_size-2.c: Moved to... + * c-c++-common/analyzer/attr-alloc_size-2.c: ...here. + * gcc.dg/analyzer/call-summaries-malloc.c: Moved to... + * c-c++-common/analyzer/call-summaries-malloc.c: ...here. + * gcc.dg/analyzer/call-summaries-pr107158-2.c: Moved to... + * c-c++-common/analyzer/call-summaries-pr107158-2.c: ...here. + * gcc.dg/analyzer/capacity-1.c: Moved to... + * c-c++-common/analyzer/capacity-1.c: ...here. + * gcc.dg/analyzer/dot-output.c: Moved to... + * c-c++-common/analyzer/dot-output.c: ...here. + * gcc.dg/analyzer/escaping-1.c: Moved to... + * c-c++-common/analyzer/escaping-1.c: ...here. + * gcc.dg/analyzer/expect-1.c: Moved to... + * c-c++-common/analyzer/expect-1.c: ...here. + * gcc.dg/analyzer/fgets-1.c: Moved to... + * c-c++-common/analyzer/fgets-1.c: ...here. + * gcc.dg/analyzer/file-uninit-1.c: Moved to... + * c-c++-common/analyzer/file-uninit-1.c: ...here. + * gcc.dg/analyzer/fileno-1.c: Moved to... + * c-c++-common/analyzer/fileno-1.c: ...here. + * gcc.dg/analyzer/first-field-1.c: Moved to... + * c-c++-common/analyzer/first-field-1.c: ...here. + * gcc.dg/analyzer/first-field-2.c: Moved to... + * c-c++-common/analyzer/first-field-2.c: ...here. + * gcc.dg/analyzer/flex-with-call-summaries.c: Moved to... + * c-c++-common/analyzer/flex-with-call-summaries.c: ...here. + * gcc.dg/analyzer/flex-without-call-summaries.c: Moved to... + * c-c++-common/analyzer/flex-without-call-summaries.c: ...here. + * gcc.dg/analyzer/flexible-array-member-1.c: Moved to... + * c-c++-common/analyzer/flexible-array-member-1.c: ...here. + * gcc.dg/analyzer/fold-string-to-char.c: Moved to... + * c-c++-common/analyzer/fold-string-to-char.c: ...here. + * gcc.dg/analyzer/fread-1.c: Moved to... + * c-c++-common/analyzer/fread-1.c: ...here. + * gcc.dg/analyzer/fread-2.c: Moved to... + * c-c++-common/analyzer/fread-2.c: ...here. + * gcc.dg/analyzer/fread-pr108661.c: Moved to... + * c-c++-common/analyzer/fread-pr108661.c: ...here. + * gcc.dg/analyzer/function-ptr-1.c: Moved to... + * c-c++-common/analyzer/function-ptr-1.c: ...here. + * gcc.dg/analyzer/function-ptr-2.c: Moved to... + * c-c++-common/analyzer/function-ptr-2.c: ...here. + * gcc.dg/analyzer/function-ptr-3.c: Moved to... + * c-c++-common/analyzer/function-ptr-3.c: ...here. + * gcc.dg/analyzer/function-ptr-4.c: Moved to... + * c-c++-common/analyzer/function-ptr-4.c: ...here. + * gcc.dg/analyzer/getc-1.c: Moved to... + * c-c++-common/analyzer/getc-1.c: ...here. + * gcc.dg/analyzer/getchar-1.c: Moved to... + * c-c++-common/analyzer/getchar-1.c: ...here. + * gcc.dg/analyzer/gzio-2.c: Moved to... + * c-c++-common/analyzer/gzio-2.c: ...here. + * gcc.dg/analyzer/gzio-3.c: Moved to... + * c-c++-common/analyzer/gzio-3.c: ...here. + * gcc.dg/analyzer/gzio-3a.c: Moved to... + * c-c++-common/analyzer/gzio-3a.c: ...here. + * gcc.dg/analyzer/gzio.c: Moved to... + * c-c++-common/analyzer/gzio.c: ...here. + * gcc.dg/analyzer/imprecise-floating-point-1.c: Moved to... + * c-c++-common/analyzer/imprecise-floating-point-1.c: ...here. + * gcc.dg/analyzer/infinite-recursion-2.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-2.c: ...here. + * gcc.dg/analyzer/infinite-recursion-3.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-3.c: ...here. + * gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-4-limited-buggy.c: ...here. + * gcc.dg/analyzer/infinite-recursion-4-limited.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-4-limited.c: ...here. + * gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-4-unlimited-buggy.c: ...here. + * gcc.dg/analyzer/infinite-recursion-4-unlimited.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-4-unlimited.c: ...here. + * gcc.dg/analyzer/infinite-recursion-5.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-5.c: ...here. + * gcc.dg/analyzer/infinite-recursion-alloca.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-alloca.c: ...here. + * gcc.dg/analyzer/infinite-recursion-inlining.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-inlining.c: ...here. + * gcc.dg/analyzer/infinite-recursion-multiline-1.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-multiline-1.c: ...here. + * gcc.dg/analyzer/infinite-recursion-multiline-2.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-multiline-2.c: ...here. + * gcc.dg/analyzer/infinite-recursion-pr108935-1.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-pr108935-1.c: ...here. + * gcc.dg/analyzer/infinite-recursion-pr108935-1a.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-pr108935-1a.c: ...here. + * gcc.dg/analyzer/infinite-recursion-pr108935-2.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-pr108935-2.c: ...here. + * gcc.dg/analyzer/infinite-recursion-variadic.c: Moved to... + * c-c++-common/analyzer/infinite-recursion-variadic.c: ...here. + * gcc.dg/analyzer/infinite-recursion.c: Moved to... + * c-c++-common/analyzer/infinite-recursion.c: ...here. + * gcc.dg/analyzer/inlining-1-multiline.c: Moved to... + * c-c++-common/analyzer/inlining-1-multiline.c: ...here. + * gcc.dg/analyzer/inlining-1-no-undo.c: Moved to... + * c-c++-common/analyzer/inlining-1-no-undo.c: ...here. + * gcc.dg/analyzer/inlining-2-multiline.c: Moved to... + * c-c++-common/analyzer/inlining-2-multiline.c: ...here. + * gcc.dg/analyzer/inlining-5-multiline.c: Moved to... + * c-c++-common/analyzer/inlining-5-multiline.c: ...here. + * gcc.dg/analyzer/inlining-6-multiline.c: Moved to... + * c-c++-common/analyzer/inlining-6-multiline.c: ...here. + * gcc.dg/analyzer/inlining-6.c: Moved to... + * c-c++-common/analyzer/inlining-6.c: ...here. + * gcc.dg/analyzer/inlining-7-multiline.c: Moved to... + * c-c++-common/analyzer/inlining-7-multiline.c: ...here. + * gcc.dg/analyzer/invalid-shift-1.c: Moved to... + * c-c++-common/analyzer/invalid-shift-1.c: ...here. + * gcc.dg/analyzer/isatty-1.c: Moved to... + * c-c++-common/analyzer/isatty-1.c: ...here. + * gcc.dg/analyzer/leak-2.c: Moved to... + * c-c++-common/analyzer/leak-2.c: ...here. + * gcc.dg/analyzer/leak-3.c: Moved to... + * c-c++-common/analyzer/leak-3.c: ...here. + * gcc.dg/analyzer/leak-4.c: Moved to... + * c-c++-common/analyzer/leak-4.c: ...here. + * gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c: Moved to... + * c-c++-common/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c: ...here. + * gcc.dg/analyzer/loop-0-up-to-n-by-1.c: Moved to... + * c-c++-common/analyzer/loop-0-up-to-n-by-1.c: ...here. + * gcc.dg/analyzer/loop-2.c: Moved to... + * c-c++-common/analyzer/loop-2.c: ...here. + * gcc.dg/analyzer/loop-2a.c: Moved to... + * c-c++-common/analyzer/loop-2a.c: ...here. + * gcc.dg/analyzer/loop-3.c: Moved to... + * c-c++-common/analyzer/loop-3.c: ...here. + * gcc.dg/analyzer/loop-4.c: Moved to... + * c-c++-common/analyzer/loop-4.c: ...here. + * gcc.dg/analyzer/loop-n-down-to-1-by-1.c: Moved to... + * c-c++-common/analyzer/loop-n-down-to-1-by-1.c: ...here. + * gcc.dg/analyzer/loop-start-down-to-end-by-1.c: Moved to... + * c-c++-common/analyzer/loop-start-down-to-end-by-1.c: ...here. + * gcc.dg/analyzer/loop-start-down-to-end-by-step.c: Moved to... + * c-c++-common/analyzer/loop-start-down-to-end-by-step.c: ...here. + * gcc.dg/analyzer/loop-start-to-end-by-step.c: Moved to... + * c-c++-common/analyzer/loop-start-to-end-by-step.c: ...here. + * gcc.dg/analyzer/loop-start-up-to-end-by-1.c: Moved to... + * c-c++-common/analyzer/loop-start-up-to-end-by-1.c: ...here. + * gcc.dg/analyzer/loop.c: Moved to... + * c-c++-common/analyzer/loop.c: ...here. + * gcc.dg/analyzer/malloc-3.c: Moved to... + * c-c++-common/analyzer/malloc-3.c: ...here. + * gcc.dg/analyzer/malloc-5.c: Moved to... + * c-c++-common/analyzer/malloc-5.c: ...here. + * gcc.dg/analyzer/malloc-CWE-401-example.c: Moved to... + * c-c++-common/analyzer/malloc-CWE-401-example.c: ...here. + * gcc.dg/analyzer/malloc-CWE-415-examples.c: Moved to... + * c-c++-common/analyzer/malloc-CWE-415-examples.c: ...here. + * gcc.dg/analyzer/malloc-CWE-416-examples.c: Moved to... + * c-c++-common/analyzer/malloc-CWE-416-examples.c: ...here. + * gcc.dg/analyzer/malloc-CWE-590-examples.c: Moved to... + * c-c++-common/analyzer/malloc-CWE-590-examples.c: ...here. + * gcc.dg/analyzer/malloc-callbacks.c: Moved to... + * c-c++-common/analyzer/malloc-callbacks.c: ...here. + * gcc.dg/analyzer/malloc-dce.c: Moved to... + * c-c++-common/analyzer/malloc-dce.c: ...here. + * gcc.dg/analyzer/malloc-dedupe-1.c: Moved to... + * c-c++-common/analyzer/malloc-dedupe-1.c: ...here. + * gcc.dg/analyzer/malloc-in-loop.c: Moved to... + * c-c++-common/analyzer/malloc-in-loop.c: ...here. + * gcc.dg/analyzer/malloc-ipa-1.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-1.c: ...here. + * gcc.dg/analyzer/malloc-ipa-11.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-11.c: ...here. + * gcc.dg/analyzer/malloc-ipa-2.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-2.c: ...here. + * gcc.dg/analyzer/malloc-ipa-3.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-3.c: ...here. + * gcc.dg/analyzer/malloc-ipa-4.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-4.c: ...here. + * gcc.dg/analyzer/malloc-ipa-5.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-5.c: ...here. + * gcc.dg/analyzer/malloc-ipa-6.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-6.c: ...here. + * gcc.dg/analyzer/malloc-ipa-7.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-7.c: ...here. + * gcc.dg/analyzer/malloc-ipa-8-unchecked.c: Moved to... + * c-c++-common/analyzer/malloc-ipa-8-unchecked.c: ...here. + * gcc.dg/analyzer/malloc-macro-inline-events.c: Moved to... + * c-c++-common/analyzer/malloc-macro-inline-events.c: ...here. + * gcc.dg/analyzer/malloc-macro-separate-events.c: Moved to... + * c-c++-common/analyzer/malloc-macro-separate-events.c: ...here. + * gcc.dg/analyzer/malloc-macro.h: Moved to... + * c-c++-common/analyzer/malloc-macro.h: ...here. + * gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c: Moved to... + * c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c: ...here. + * gcc.dg/analyzer/out-of-bounds-1.c: Moved to... + * c-c++-common/analyzer/out-of-bounds-1.c: ...here. + * gcc.dg/analyzer/out-of-bounds-2.c: Moved to... + * c-c++-common/analyzer/out-of-bounds-2.c: ...here. + * gcc.dg/analyzer/out-of-bounds-5.c: Moved to... + * c-c++-common/analyzer/out-of-bounds-5.c: ...here. + * gcc.dg/analyzer/out-of-bounds-diagram-11.c: Moved to... + * c-c++-common/analyzer/out-of-bounds-diagram-11.c: ...here. + * gcc.dg/analyzer/out-of-bounds-diagram-3.c: Moved to... + * c-c++-common/analyzer/out-of-bounds-diagram-3.c: ...here. + * gcc.dg/analyzer/out-of-bounds-diagram-8.c: Moved to... + * c-c++-common/analyzer/out-of-bounds-diagram-8.c: ...here. + * gcc.dg/analyzer/phi-1.c: Moved to... + * c-c++-common/analyzer/phi-1.c: ...here. + * gcc.dg/analyzer/pr100615.c: Moved to... + * c-c++-common/analyzer/pr100615.c: ...here. + * gcc.dg/analyzer/pr103526.c: Moved to... + * c-c++-common/analyzer/pr103526.c: ...here. + * gcc.dg/analyzer/pr94362-1.c: Moved to... + * c-c++-common/analyzer/pr94362-1.c: ...here. + * gcc.dg/analyzer/pr97074.c: Moved to... + * c-c++-common/analyzer/pr97074.c: ...here. + * c-c++-common/analyzer/pr99193-2.c: Added include. + * c-c++-common/analyzer/realloc-1.c: Added include. + * gcc.dg/analyzer/scope-1.c: Moved to... + * c-c++-common/analyzer/scope-1.c: ...here. + * gcc.dg/analyzer/setjmp-2.c: Moved to... + * c-c++-common/analyzer/setjmp-2.c: ...here. + * gcc.dg/analyzer/setjmp-5.c: Moved to... + * c-c++-common/analyzer/setjmp-5.c: ...here. + * gcc.dg/analyzer/setjmp-9.c: Moved to... + * c-c++-common/analyzer/setjmp-9.c: ...here. + * gcc.dg/analyzer/signal-4a.c: Moved to... + * c-c++-common/analyzer/signal-4a.c: ...here. + * gcc.dg/analyzer/signal-4b.c: Moved to... + * c-c++-common/analyzer/signal-4b.c: ...here. + * gcc.dg/analyzer/file-pr58237.c: C only. + * gcc.dg/analyzer/fopen-1.c: C only. + * gcc.dg/analyzer/malloc-4.c: C only. + * gcc.dg/analyzer/malloc-paths-9.c: C only. + * gcc.dg/analyzer/pr103892.c: C only. + * gcc.dg/analyzer/pr109577.c: C only. + * gcc.dg/analyzer/pr93355-localealias-feasibility.c: C only. + * gcc.dg/analyzer/pr99193-1.c: C only. + * gcc.dg/analyzer/compound-assignment-1.c: Removed. + * gcc.dg/analyzer/inlining-1.c: Removed. + * gcc.dg/analyzer/inlining-2.c: Removed. + * gcc.dg/analyzer/inlining-5.c: Removed. + * gcc.dg/analyzer/inlining-7.c: Removed. + * c-c++-common/analyzer/compound-assignment-1.c: New test. + * c-c++-common/analyzer/file-pr58237-noexcept.c: Duplicate of + gcc.dg/analyzer/file-pr58237.c with exceptions disabled. + * c-c++-common/analyzer/fopen-2.c: C++ compatible parts from + gcc.dg/analyzer/fopen-1.c. + * c-c++-common/analyzer/inlining-1.c: New test. + * c-c++-common/analyzer/inlining-2.c: New test. + * c-c++-common/analyzer/inlining-5.c: New test. + * c-c++-common/analyzer/inlining-7.c: New test. + * c-c++-common/analyzer/malloc-paths-9-noexcept.c: Duplicate of + gcc.dg/analyzer/malloc-paths-9.c with exceptions disabled. + * c-c++-common/analyzer/pr109577-noexcept.c: Duplicate of + gcc.dg/analyzer/pr109577.c with exceptions disabled. + * c-c++-common/analyzer/pr93355-localealias-feasibility-noexcept.c: + Duplicate of gcc.dg/analyzer/pr93355-localealias-feasibility.c with + exceptions disabled. + * c-c++-common/analyzer/pr99193-1-noexcept.c: Duplicate of + gcc.dg/analyzer/pr99193-1.c with exceptions disabled. + +2023-09-09 Xi Ruoyao <xry111@xry111.site> + + * gcc.target/loongarch/memcpy-vec-3.c: Increase the amount of + copied bytes to 32. + +2023-09-09 Lulu Cheng <chenglulu@loongson.cn> + + * gcc.target/loongarch/mulw_d_wu.c: New test. + * gcc.target/loongarch/smuldi3_highpart.c: New test. + * gcc.target/loongarch/smulsi3_highpart.c: New test. + * gcc.target/loongarch/umulsi3_highpart.c: New test. + +2023-09-09 Xi Ruoyao <xry111@xry111.site> + + * gcc.target/loongarch/memcpy-vec-1.c: New test. + * gcc.target/loongarch/memcpy-vec-2.c: New test. + * gcc.target/loongarch/memcpy-vec-3.c: New test. + +2023-09-09 Lehua Ding <lehua.ding@rivai.ai> + + * gcc.target/riscv/rvv/autovec/vls/div-1.c: Adjust. + * gcc.target/riscv/rvv/autovec/vls/shift-3.c: Adjust. + * gcc.target/riscv/rvv/autovec/fold-min-poly.c: New test. + +2023-09-08 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + * gcc.dg/darwin-segaddr.c: Adjust for darwin linker warning. + * gcc.dg/pie-7.c: Likewise. + +2023-09-08 Patrick Palka <ppalka@redhat.com> + + PR c++/99599 + * g++.dg/cpp2a/concepts-recursive-sat4.C: Make 'Int' non-aggregate + in order to preserve intent of the testcase. + * g++.dg/cpp2a/concepts-nondep4.C: New test. + +2023-09-08 Christoph Müllner <christoph.muellner@vrull.eu> + + * gcc.target/riscv/xtheadbb-ext-2.c: New test. + * gcc.target/riscv/xtheadbb-ext-3.c: New test. + +2023-09-07 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/110529 + * c-c++-common/analyzer/computed-goto-1.c: New test. + * gcc.dg/analyzer/computed-goto-pr110529.c: New test. + +2023-09-07 benjamin priour <vultkayn@gcc.gnu.org> + David Malcolm <dmalcolm@redhat.com> + + PR analyzer/110830 + * c-c++-common/analyzer/pr110830.c: New test. + +2023-09-07 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/110875 + * gcc.dg/pr110875.c: New. + +2023-09-07 Sandra Loosemore <sandra@codesourcery.com> + + PR c++/111274 + * g++.dg/gomp/pr111274.C: New test case. + +2023-09-07 Vladimir N. Makarov <vmakarov@redhat.com> + + PR target/111225 + * gcc.target/i386/pr111225.c: New test. + +2023-09-07 David Malcolm <dmalcolm@redhat.com> + + * rust/compile/bad_as_bool_char.rs: Add error code to testcase. + +2023-09-07 Xi Ruoyao <xry111@xry111.site> + + * g++.target/loongarch/bstrins-compile.C: New test. + * g++.target/loongarch/bstrins-run.C: New test. + +2023-09-07 Juzhe-Zhong <juzhe.zhong@rivai.ai> + + PR target/111313 + * gcc.target/riscv/rvv/vsetvl/avl_single-13.c: Adapt test. + * gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-17.c: Skip check for O1. + * gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-18.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-19.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_bb_prop-20.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-1.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-10.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-11.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-12.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-13.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-14.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-15.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-16.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-17.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-18.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-19.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-2.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-20.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-21.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-22.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-23.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-24.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-25.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-26.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-27.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-28.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-3.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-4.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-5.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-6.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-7.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-8.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_phi-9.c: Ditto. + * gcc.target/riscv/rvv/vsetvl/vlmax_switch_vtype-2.c: Ditto. + * gcc.target/riscv/rvv/autovec/pr111313.c: New test. + +2023-09-07 Tsukasa OI <research_trasio@irq.a4lg.com> + + * gcc.target/riscv/xventanacondops-primitiveSemantics.c: New test, + * gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c: New + test to make sure that XVentanaCondOps instructions are disabled + on RV32. + * gcc.target/riscv/xventanacondops-xor-01.c: New test, + 2023-09-06 Ian Lance Taylor <iant@golang.org> PR go/111310 diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-1.c index 003914e..05efc4f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-1.c @@ -6,18 +6,19 @@ void test_1 (void) { - int16_t *ptr = malloc (21 * sizeof (int16_t)); + int16_t *ptr = (int16_t *) malloc (21 * sizeof (int16_t)); free (ptr); } void test_2 (void) { - int32_t *ptr = malloc (21 * sizeof (int16_t)); /* { dg-line malloc2 } */ + int32_t *ptr = (int32_t *) malloc (21 * sizeof (int16_t)); /* { dg-line malloc2 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ /* { dg-message "42 bytes" "note" { target *-*-* } malloc2 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } malloc2 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } malloc2 } */ } void test_3 (void) @@ -34,7 +35,8 @@ void test_4 (void) free (iptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign4 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign4 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } assign4 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } assign4 } */ } void test_5 (void) @@ -67,7 +69,8 @@ void test_6 (void) free (iptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign6 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign6 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } assign6 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } assign6 } */ } void test_7 (void) @@ -94,7 +97,7 @@ void *create_buffer (int32_t n) void test_8 (void) { - int32_t *buf = create_buffer(4 * sizeof (int)); + int32_t *buf = (int32_t *) create_buffer(4 * sizeof (int)); free (buf); } @@ -106,22 +109,23 @@ void test_9 (void) impl_region_model_context::warn. To ensure that the indentation in the diagnostic is right, the warning has to be emitted on an EN that is after the return edge. */ - int32_t *buf = create_buffer(42); /* { dg-warning "" "" { xfail *-*-* } } */ + int32_t *buf = (int32_t *) create_buffer(42); /* { dg-warning "" "" { xfail *-*-* } } */ free (buf); } void test_10 (int32_t n) { - char *ptr = malloc (7 * n); + char *ptr = (char *) malloc (7 * n); free (ptr); } void test_11 () { /* 3.0 is folded to an int before the analyzer runs. */ - int32_t *ptr = malloc (3.0); /* { dg-line malloc11 } */ + int32_t *ptr = (int32_t *) malloc (3.0); /* { dg-line malloc11 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc11 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc11 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } malloc11 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } malloc11 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-2.c index eb770f7..ff4cb56 100644 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-2.c @@ -9,18 +9,19 @@ void test_1 (int32_t n) { - int16_t *ptr = malloc (n * sizeof (int16_t)); + int16_t *ptr = (int16_t *)malloc (n * sizeof (int16_t)); free (ptr); } void test_2 (int32_t n) { - int32_t *ptr = malloc (n * sizeof (int16_t)); /* { dg-line malloc2 } */ + int32_t *ptr = (int32_t *)malloc (n * sizeof (int16_t)); /* { dg-line malloc2 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ /* { dg-message "'\[a-z0-9\\*\\(\\)\\s\]*' bytes" "note" { target *-*-* } malloc2 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4" "note" { target c } malloc2 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4" "note" { target c++ } malloc2 } */ } void test_3 (int32_t n) @@ -37,7 +38,8 @@ void test_4 (int32_t n) free (iptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign4 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign4 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } assign4 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } assign4 } */ } void test_5 (void) @@ -78,7 +80,7 @@ void *create_buffer(int32_t n) void test_7(int32_t n) { - int32_t *buf = create_buffer(n * sizeof (int32_t)); + int32_t *buf = (int32_t *)create_buffer(n * sizeof (int32_t)); free (buf); } @@ -90,7 +92,7 @@ void test_8(int32_t n) impl_region_model_context::warn. To ensure that the indentation in the diagnostic is right, the warning has to be emitted on an EN that is after the return edge. */ - int32_t *buf = create_buffer(n * sizeof(int16_t)); /* { dg-warning "" "" { xfail *-*-* } } */ + int32_t *buf = (int32_t *)create_buffer(n * sizeof(int16_t)); /* { dg-warning "" "" { xfail *-*-* } } */ free (buf); } @@ -136,7 +138,8 @@ void test_12 (void) else free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign12 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign12 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } assign12 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } assign12 } */ } void test_13 (void) @@ -162,6 +165,6 @@ int *test_14 (size_t n) /* n is an initial_svalue and guarded such that there is no equiv_class for n itself but only for a binop_svalue containing n. */ if (n % sizeof (int) == 0) - ptr = malloc (n); + ptr = (int *)malloc (n); return ptr; } diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-3.c index 6751441..4e99e88 100644 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-3.c @@ -21,31 +21,34 @@ void test_1 (void) /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc1 } */ /* { dg-message "3 bytes" "note" { target *-*-* } malloc1 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc1 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } malloc1 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } malloc1 } */ } void test_2 (void) { - int32_t *ptr = malloc (10 + sizeof(int32_t)); /* { dg-line malloc2 } */ + int32_t *ptr = (int32_t *) malloc (10 + sizeof(int32_t)); /* { dg-line malloc2 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ /* { dg-message "14 bytes" "note" { target *-*-* } malloc2 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } malloc2 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } malloc2 } */ } void test_3 (int32_t n) { - int32_t *ptr = malloc (n + sizeof (int32_t)); /* { dg-line malloc3 } */ + int32_t *ptr = (int32_t *) malloc (n + sizeof (int32_t)); /* { dg-line malloc3 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc3 } */ /* { dg-message "'\[a-z0-9\\+\\(\\)\\s\]*' bytes" "note" { target *-*-* } malloc3 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc3 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } malloc3 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } malloc3 } */ } void test_4 (int32_t n, int32_t m) { - int32_t *ptr = malloc ((n + m) * sizeof (int32_t)); + int32_t *ptr = (int32_t *) malloc ((n + m) * sizeof (int32_t)); free (ptr); } diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-4.c index a56b25b..7d07ba6 100644 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-4.c @@ -20,31 +20,32 @@ struct var_len { void test_1 (void) { - struct base *ptr = malloc (5 * sizeof (struct base)); + struct base *ptr = (struct base *) malloc (5 * sizeof (struct base)); free (ptr); } void test_2 (void) { - int32_t *ptr = malloc (5 * sizeof (struct base)); /* { dg-line malloc2 } */ + int32_t *ptr = (int32_t *) malloc (5 * sizeof (struct base)); /* { dg-line malloc2 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ /* { dg-message "\\d+ bytes" "note" { target *-*-* } malloc2 } */ - /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c } malloc2 } */ + /* { dg-message "'int32_t\\*' (\\\{aka '(long )?int\\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target c++ } malloc2 } */ } void test_3 (void) { /* Even though 10 bytes is not a multiple of 4, we do not warn to prevent a false positive in case s is the base struct of a struct inheritance. */ - struct base *ptr = malloc (10); + struct base *ptr = (struct base *) malloc (10); free (ptr); } void test_4 (void) { - struct var_len *ptr = malloc (10); + struct var_len *ptr = (struct var_len *) malloc (10); free (ptr); } @@ -52,10 +53,11 @@ void test_5 (void) { /* For constant sizes, we warn if the buffer is too small to hold a single struct. */ - struct base *ptr = malloc (1); /* { dg-line malloc5 } */ + struct base *ptr = (struct base *) malloc (1); /* { dg-line malloc5 } */ free (ptr); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc5 } */ /* { dg-message "allocated 1 byte here" "note" { target *-*-* } malloc5 } */ - /* { dg-message "'struct base \\*' here; 'sizeof \\(struct base\\)' is '\\d+'" "note" { target *-*-* } malloc5 } */ + /* { dg-message "'struct base \\*' here; 'sizeof \\(struct base\\)' is '\\d+'" "note" { target c } malloc5 } */ + /* { dg-message "'base\\*' here; 'sizeof \\(base\\)' is '\\d+'" "note" { target c++ } malloc5 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-0.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-0.c index f21cd37..24fe84d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-0.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-0.c @@ -58,7 +58,46 @@ void test_1 (void *ptr, int a, int b) | | | | | (5) second 'free' here; first 'free' was at (2) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_1(void*, int, int)': event 1 + | + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (1) calling 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': event 2 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (2) first 'free' here + | + <------+ + | + 'void test_1(void*, int, int)': events 3-4 + | + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (3) returning to 'test_1' from 'calls_free_1' + |...... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (4) passing freed pointer 'ptr' in call to 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': event 5 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (5) second 'free' here; first 'free' was at (2) + | + { dg-end-multiline-output "" { target c++ } } */ void calls_free_2 (void *ptr) { @@ -128,7 +167,46 @@ void test_2 (void *ptr, int a, int b) | | | | | (5) second 'free' here; first 'free' was at (2) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_2(void*, int, int)': event 1 + | + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (1) calling 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': event 2 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (2) first 'free' here + | + <------+ + | + 'void test_2(void*, int, int)': events 3-4 + | + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (3) returning to 'test_2' from 'calls_free_2' + |...... + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (4) passing freed pointer 'ptr' in call to 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': event 5 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (5) second 'free' here; first 'free' was at (2) + | + { dg-end-multiline-output "" { target c++ } } */ // TODO: range cases @@ -160,4 +238,20 @@ void test_3 (void *ptr) | | | | | (2) second 'free' here; first 'free' was at (1) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_3(void*)': events 1-2 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (1) first 'free' here + | NN | called_by_test_3 (); + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (2) second 'free' here; first 'free' was at (1) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-1.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-1.c index 6d6e70a..e134370 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-1.c @@ -73,7 +73,61 @@ void test_1 (void *ptr, int a, int b) | | | | | (8) second 'free' here; first 'free' was at (4) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_1(void*, int, int)': events 1-2 + | + | NN | void test_1 (void *ptr, int a, int b) + | | ^~~~~~ + | | | + | | (1) entry to 'test_1' + |...... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (2) calling 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': events 3-4 + | + | NN | void calls_free_1 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (3) entry to 'calls_free_1' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (4) first 'free' here + | + <------+ + | + 'void test_1(void*, int, int)': events 5-6 + | + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (5) returning to 'test_1' from 'calls_free_1' + |...... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (6) passing freed pointer 'ptr' in call to 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': events 7-8 + | + | NN | void calls_free_1 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (7) entry to 'calls_free_1' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (8) second 'free' here; first 'free' was at (4) + | + { dg-end-multiline-output "" { target c++ } } */ void calls_free_2 (void *ptr) { @@ -158,7 +212,61 @@ void test_2 (void *ptr, int a, int b) | | | | | (8) second 'free' here; first 'free' was at (4) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_2(void*, int, int)': events 1-2 + | + | NN | void test_2 (void *ptr, int a, int b) + | | ^~~~~~ + | | | + | | (1) entry to 'test_2' + |...... + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (2) calling 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': events 3-4 + | + | NN | void calls_free_2 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (3) entry to 'calls_free_2' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (4) first 'free' here + | + <------+ + | + 'void test_2(void*, int, int)': events 5-6 + | + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (5) returning to 'test_2' from 'calls_free_2' + |...... + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (6) passing freed pointer 'ptr' in call to 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': events 7-8 + | + | NN | void calls_free_2 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (7) entry to 'calls_free_2' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (8) second 'free' here; first 'free' was at (4) + | + { dg-end-multiline-output "" { target c++ } } */ /* The call/return to this function shouldn't appear in the path. */ @@ -188,4 +296,20 @@ void test_3 (void *ptr) | | | | | (2) second 'free' here; first 'free' was at (1) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_3(void*)': events 1-2 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (1) first 'free' here + | NN | called_by_test_3 (); + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (2) second 'free' here; first 'free' was at (1) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-2.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-2.c index 3d3316a..0fd8654 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-2.c @@ -84,7 +84,72 @@ void test_1 (void *ptr, int a, int b) | | | | | (12) second 'free' here; first 'free' was at (6) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_1(void*, int, int)': events 1-4 + | + | NN | void test_1 (void *ptr, int a, int b) + | | ^~~~~~ + | | | + | | (1) entry to 'test_1' + | NN | { + | NN | if (a) + | | ~~ + | | | + | | (2) following 'true' branch (when 'a != 0')... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (3) ...to here + | | (4) calling 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': events 5-6 + | + | NN | void calls_free_1 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (5) entry to 'calls_free_1' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) first 'free' here + | + <------+ + | + 'void test_1(void*, int, int)': events 7-10 + | + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (7) returning to 'test_1' from 'calls_free_1' + | NN | + | NN | if (b) + | | ~~ + | | | + | | (8) following 'false' branch (when 'b == 0')... + |...... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (9) ...to here + | | (10) passing freed pointer 'ptr' in call to 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': events 11-12 + | + | NN | void calls_free_1 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (11) entry to 'calls_free_1' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (12) second 'free' here; first 'free' was at (6) + | + { dg-end-multiline-output "" { target c++ } } */ void calls_free_2 (void *ptr) { @@ -187,7 +252,79 @@ void test_2 (void *ptr, int a, int b) | | | | | (12) second 'free' here; first 'free' was at (6) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_2(void*, int, int)': events 1-4 + | + | NN | void test_2 (void *ptr, int a, int b) + | | ^~~~~~ + | | | + | | (1) entry to 'test_2' + | NN | { + | NN | switch (a) + | | ~~~~~~ + | | | + | | (2) following 'case 3:' branch... + |...... + | NN | case 3: + | | ~~~~ + | | | + | | (3) ...to here + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (4) calling 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': events 5-6 + | + | NN | void calls_free_2 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (5) entry to 'calls_free_2' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) first 'free' here + | + <------+ + | + 'void test_2(void*, int, int)': events 7-10 + | + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (7) returning to 'test_2' from 'calls_free_2' + |...... + | NN | switch (b) + | | ~~~~~~ + | | | + | | (8) following 'default:' branch... + | NN | { + | NN | default: + | | ~~~~~~~ + | | | + | | (9) ...to here + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (10) passing freed pointer 'ptr' in call to 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': events 11-12 + | + | NN | void calls_free_2 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (11) entry to 'calls_free_2' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (12) second 'free' here; first 'free' was at (6) + | + { dg-end-multiline-output "" { target c++ } } */ // TODO: range cases @@ -219,4 +356,20 @@ void test_3 (void *ptr) | | | | | (2) second 'free' here; first 'free' was at (1) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_3(void*)': events 1-2 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (1) first 'free' here + | NN | called_by_test_3 (); + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (2) second 'free' here; first 'free' was at (1) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-3.c b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-3.c index fb87d16..ac699ec 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-verbosity-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-verbosity-3.c @@ -84,7 +84,72 @@ void test_1 (void *ptr, int a, int b) | | | | | (12) second 'free' here; first 'free' was at (6) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_1(void*, int, int)': events 1-4 + | + | NN | void test_1 (void *ptr, int a, int b) + | | ^~~~~~ + | | | + | | (1) entry to 'test_1' + | NN | { + | NN | if (a) + | | ~~ + | | | + | | (2) following 'true' branch (when 'a != 0')... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (3) ...to here + | | (4) calling 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': events 5-6 + | + | NN | void calls_free_1 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (5) entry to 'calls_free_1' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) first 'free' here + | + <------+ + | + 'void test_1(void*, int, int)': events 7-10 + | + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (7) returning to 'test_1' from 'calls_free_1' + | NN | + | NN | if (b) + | | ~~ + | | | + | | (8) following 'false' branch (when 'b == 0')... + |...... + | NN | calls_free_1 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (9) ...to here + | | (10) passing freed pointer 'ptr' in call to 'calls_free_1' from 'test_1' + | + +--> 'void calls_free_1(void*)': events 11-12 + | + | NN | void calls_free_1 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (11) entry to 'calls_free_1' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (12) second 'free' here; first 'free' was at (6) + | + { dg-end-multiline-output "" { target c++ } } */ void calls_free_2 (void *ptr) { @@ -187,7 +252,79 @@ void test_2 (void *ptr, int a, int b) | | | | | (12) second 'free' here; first 'free' was at (6) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_2(void*, int, int)': events 1-4 + | + | NN | void test_2 (void *ptr, int a, int b) + | | ^~~~~~ + | | | + | | (1) entry to 'test_2' + | NN | { + | NN | switch (a) + | | ~~~~~~ + | | | + | | (2) following 'case 3:' branch... + |...... + | NN | case 3: + | | ~~~~ + | | | + | | (3) ...to here + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (4) calling 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': events 5-6 + | + | NN | void calls_free_2 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (5) entry to 'calls_free_2' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) first 'free' here + | + <------+ + | + 'void test_2(void*, int, int)': events 7-10 + | + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~^~~~~ + | | | + | | (7) returning to 'test_2' from 'calls_free_2' + |...... + | NN | switch (b) + | | ~~~~~~ + | | | + | | (8) following 'default:' branch... + | NN | { + | NN | default: + | | ~~~~~~~ + | | | + | | (9) ...to here + | NN | calls_free_2 (ptr); + | | ~~~~~~~~~~~~~~~~~~ + | | | + | | (10) passing freed pointer 'ptr' in call to 'calls_free_2' from 'test_2' + | + +--> 'void calls_free_2(void*)': events 11-12 + | + | NN | void calls_free_2 (void *ptr) + | | ^~~~~~~~~~~~ + | | | + | | (11) entry to 'calls_free_2' + | NN | { + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (12) second 'free' here; first 'free' was at (6) + | + { dg-end-multiline-output "" { target c++ } } */ // TODO: range cases @@ -219,4 +356,20 @@ void test_3 (void *ptr) | | | | | (2) second 'free' here; first 'free' was at (1) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_3(void*)': events 1-2 + | + | NN | free (ptr); + | | ~~~~~^~~~~ + | | | + | | (1) first 'free' here + | NN | called_by_test_3 (); + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (2) second 'free' here; first 'free' was at (1) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-alloc_size-1.c b/gcc/testsuite/c-c++-common/analyzer/attr-alloc_size-1.c index eb3c695..650d3f5 100644 --- a/gcc/testsuite/gcc.dg/analyzer/attr-alloc_size-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/attr-alloc_size-1.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef __SIZE_TYPE__ size_t; @@ -7,7 +7,7 @@ extern void* (*my_alloc_2)(size_t, size_t) __attribute__ ((alloc_size (1, 2))); int test_one_arg_concrete_int_ptr (void) { - int *x = my_alloc (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + int *x = (int *) my_alloc (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ __analyzer_dump_capacity (x); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)1'" } */ x[0] = 0; /* { dg-warning "buffer overflow" } */ return 0; @@ -15,7 +15,7 @@ int test_one_arg_concrete_int_ptr (void) void test_one_arg_concrete (void) { - char *p = my_alloc (10); + char *p = (char *) my_alloc (10); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)10'" } */ p[0] = 'a'; p[9] = 'b'; @@ -25,13 +25,13 @@ void test_one_arg_concrete (void) void test_one_arg_symbolic (size_t sz) { - char *p = my_alloc (sz); + char *p = (char *) my_alloc (sz); __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'INIT_VAL\\(sz" } */ } void test_two_args_concrete (void) { - char *p = my_alloc_2 (2, 5); + char *p = (char *) my_alloc_2 (2, 5); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)10'" } */ p[0] = 'a'; p[9] = 'b'; @@ -41,19 +41,19 @@ void test_two_args_concrete (void) void test_two_args_symbolic_first (size_t sz) { - char *p = my_alloc_2 (sz, 5); + char *p = (char *) my_alloc_2 (sz, 5); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(INIT_VAL\\(sz\[^\n\r\]*\\*\\(size_t\\)5\\)'" } */ } void test_two_args_symbolic_second (size_t sz) { - char *p = my_alloc_2 (5, sz); + char *p = (char *) my_alloc_2 (5, sz); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(INIT_VAL\\(sz\[^\n\r\]*\\*\\(size_t\\)5\\)'" } */ } void test_two_args_symbolic_both (size_t a, size_t b) { - char *p = my_alloc_2 (a, b); + char *p = (char *) my_alloc_2 (a, b); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(INIT_VAL\\(a\[^\n\r\]*\\*INIT_VAL\\(b" } */ } @@ -62,7 +62,7 @@ typedef void* (*my_alloc_2_t)(size_t, size_t) __attribute__ ((alloc_size (1, 2)) void test_one_arg_concrete_fnptr (my_alloc_t fnptr) { - char *p = fnptr (10); + char *p = (char *) fnptr (10); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)10'" } */ p[0] = 'a'; p[9] = 'b'; @@ -72,7 +72,7 @@ void test_one_arg_concrete_fnptr (my_alloc_t fnptr) void test_two_args_concrete_fnptr (my_alloc_2_t fnptr) { - char *p = fnptr (2, 5); + char *p = (char *) fnptr (2, 5); __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)10'" } */ p[0] = 'a'; p[9] = 'b'; diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-alloc_size-2.c b/gcc/testsuite/c-c++-common/analyzer/attr-alloc_size-2.c index 7b787f9..47f0ba4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/attr-alloc_size-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/attr-alloc_size-2.c @@ -6,7 +6,7 @@ void *xirealloc (void *p, idx_t s) char * test_cast_1 (char *buf, idx_t buf_count) { - return xirealloc (buf, buf_count + 1); + return (char *) xirealloc (buf, buf_count + 1); } void *alloc_cast_2 (signed char x, signed char y) diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-malloc.c b/gcc/testsuite/c-c++-common/analyzer/call-summaries-malloc.c index 87173a0..15c4c2e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-malloc.c +++ b/gcc/testsuite/c-c++-common/analyzer/call-summaries-malloc.c @@ -6,11 +6,11 @@ #include <stdlib.h> #include <string.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" int *malloc_int (int i) { - int *res = malloc (sizeof (int)); + int *res = (int *) malloc (sizeof (int)); if (!res) return NULL; *res = i; @@ -34,7 +34,8 @@ void test_malloc_int (int x) void test_leak (int x) { - int *p = malloc_int (x); /* { dg-message "when 'malloc_int' returns pointer to heap-allocated buffer" } */ + int *p = malloc_int (x); /* { dg-message "when 'malloc_int' returns pointer to heap-allocated buffer" "" { target c } } */ + /* { dg-message "when 'int\\* malloc_int\\(int\\)' returns pointer to heap-allocated buffer" "" { target c++ } .-1 } */ } /* { dg-message "leak of 'p'" } */ void *wrapped_malloc (size_t sz) @@ -64,14 +65,14 @@ void test_use_after_free (void) void test_use_without_check (size_t sz) { - char *buf = wrapped_malloc (sz); /* { dg-message "this call could return NULL" } */ + char *buf = (char *) wrapped_malloc (sz); /* { dg-message "this call could return NULL" } */ memset (buf, 'x', sz); /* { dg-warning "use of possibly-NULL 'buf' where non-null expected" } */ wrapped_free (buf); } void test_out_of_bounds (size_t sz) { - char *buf = wrapped_malloc (sz); + char *buf = (char *) wrapped_malloc (sz); if (!buf) return; memset (buf, 'x', sz); diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c index c2e9e2ba..4561e10 100644 --- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c @@ -1,4 +1,9 @@ /* { dg-additional-options "-fanalyzer-call-summaries -Wno-analyzer-too-complex" } */ +/* { dg-skip-if "c++98 has no noreturn attribute" { c++98_only } } */ + +#ifdef __cplusplus +#define _Noreturn [[noreturn]] +#endif typedef __SIZE_TYPE__ size_t; typedef struct _IO_FILE FILE; @@ -36,7 +41,7 @@ _Noreturn static void failed(const char *message) { static char *string_dup(const char *string) { char *buf; - if ((buf = malloc(strlen(string) + 1)) == ((void *)0)) + if ((buf = (char *) malloc(strlen(string) + 1)) == ((void *)0)) failed("malloc() failed"); return strcpy(buf, string); @@ -48,7 +53,7 @@ static void store_data(const char *name, const char *type) { if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0)) failed("malloc() failed"); - p->link = ((void *)0); + p->link = (struct mydata *)((void *)0); p->name = string_dup(name); p->type = string_dup(type); diff --git a/gcc/testsuite/gcc.dg/analyzer/capacity-1.c b/gcc/testsuite/c-c++-common/analyzer/capacity-1.c index 2d12483..ae31ced 100644 --- a/gcc/testsuite/gcc.dg/analyzer/capacity-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/capacity-1.c @@ -1,7 +1,7 @@ /* { dg-require-effective-target alloca } */ #include <stdlib.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef unsigned __INT32_TYPE__ u32; @@ -89,7 +89,7 @@ struct s static struct s * __attribute__((noinline)) alloc_s (size_t num) { - struct s *p = malloc (sizeof(struct s) + num); + struct s *p = (struct s *) malloc (sizeof(struct s) + num); return p; } diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c new file mode 100644 index 0000000..0ab006d --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-1.c @@ -0,0 +1,72 @@ +#include <stdlib.h> + +struct ptr_wrapper +{ + int *ptr; +}; + +struct ptr_wrapper +test_1 (void) +{ + struct ptr_wrapper r; + r.ptr = (int *) malloc (sizeof (int)); + return r; +} + +struct ptr_wrapper +test_2 (void) +{ + struct ptr_wrapper r, s; + r.ptr = (int *) malloc (sizeof (int)); + s = r; + return s; +} + +struct nested +{ + struct ptr_wrapper w; +}; + +struct nested +test_3 (void) +{ + struct nested n; + n.w.ptr = (int *) malloc (sizeof (int)); + return n; +} + +void test_4 (void) +{ + struct ptr_wrapper r; + r.ptr = (int *) malloc (sizeof (int)); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'r.ptr'" "" { target c } } */ +/* { dg-warning "leak of 'r.ptr_wrapper::ptr'" "" { target c++ } .-1 } */ +/* { dg-bogus "leak of '<unknown>'" "unknown leak" { target *-*-* } .-1 } */ + +static struct ptr_wrapper __attribute__((noinline)) +called_by_test_5a (void) +{ + struct ptr_wrapper r; + r.ptr = (int *) malloc (sizeof (int)); /* { dg-message "allocated here" } */ + return r; +} + +void test_5a (void) +{ + struct ptr_wrapper q = called_by_test_5a (); +} /* { dg-warning "leak of 'q.ptr'" "" { target c } } */ +/* { dg-warning "leak of 'q.ptr_wrapper::ptr'" "" { target c++ } .-1 } */ + +static struct ptr_wrapper __attribute__((noinline)) +called_by_test_5b (void) +{ + struct ptr_wrapper r; + r.ptr = (int *) malloc (sizeof (int)); + return r; /* { dg-warning "leak of '<return-value>.ptr'" "" { target c } } */ + /* TODO: show the allocation point; improve above messages. C++ does show it. */ +} + +void test_5b (void) +{ + called_by_test_5b (); +} /* { dg-warning "leak of '<anonymous>.ptr_wrapper::ptr'" "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/computed-goto-1.c b/gcc/testsuite/c-c++-common/analyzer/computed-goto-1.c new file mode 100644 index 0000000..d6877d3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/computed-goto-1.c @@ -0,0 +1,60 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +void test_1 (int pc) +{ + void *arr[2] = {&&x, &&y}; + + goto *arr[pc]; + +x: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 0); /* { dg-warning "TRUE" "true" { xfail *-*-* } .-1 } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + return; + + y: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 1); /* { dg-warning "TRUE" "" { xfail *-*-* } } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + return; +} + +void test_duplicates (int pc) +{ + void *arr[3] = {&&x, &&y, &&x}; + int var = 0; + + goto *arr[pc]; + + x: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 0); /* { dg-warning "UNKNOWN" } */ + return; + + y: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 1); /* { dg-warning "TRUE" "" { xfail *-*-* } } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + return; +} + +void test_multiple (int pc) +{ + void *arr[2] = {&&x, &&y}; + + goto *arr[pc]; + +x: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 0); /* { dg-warning "TRUE" "true" { xfail *-*-* } .-1 } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + + goto *arr[pc]; + + y: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 1); /* { dg-warning "TRUE" "" { xfail *-*-* } } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + + goto *arr[pc]; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/dot-output.c b/gcc/testsuite/c-c++-common/analyzer/dot-output.c index 03405cd..b1badd7 100644 --- a/gcc/testsuite/gcc.dg/analyzer/dot-output.c +++ b/gcc/testsuite/c-c++-common/analyzer/dot-output.c @@ -14,7 +14,7 @@ int some_call (int i, char ch) int *test (int *buf, int n, int *out) { int i; - int *result = malloc (sizeof (int) * n); + int *result = (int *) malloc (sizeof (int) * n); /* A loop, to ensure we have phi nodes. */ for (i = 0; i < n; i++) diff --git a/gcc/testsuite/gcc.dg/analyzer/escaping-1.c b/gcc/testsuite/c-c++-common/analyzer/escaping-1.c index 2dfd02b..b389656 100644 --- a/gcc/testsuite/gcc.dg/analyzer/escaping-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/escaping-1.c @@ -1,6 +1,4 @@ -#include "analyzer-decls.h" - -#define NULL ((void *)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern void unknown_fn (void *); @@ -15,13 +13,16 @@ static void test_1 (void) __analyzer_dump_escaped (); /* { dg-warning "escaped: 0: " } */ unknown_fn (&local_1); - __analyzer_dump_escaped (); /* { dg-warning "escaped: 1: 'local_1'" } */ + __analyzer_dump_escaped (); /* { dg-warning "escaped: 1: 'local_1'" "" { target c } } */ + /* { dg-warning "escaped: 1: 'int local_1'" "" { target c++ } .-1 } */ /* Should be idempotent. */ unknown_fn (&local_1); - __analyzer_dump_escaped (); /* { dg-warning "escaped: 1: 'local_1'" } */ + __analyzer_dump_escaped (); /* { dg-warning "escaped: 1: 'local_1'" "" { target c } } */ + /* { dg-warning "escaped: 1: 'int local_1'" "" { target c++ } .-1 } */ /* Escape a static global. */ unknown_fn (&only_used_by_test_1); - __analyzer_dump_escaped (); /* { dg-warning "escaped: 2: 'local_1', 'only_used_by_test_1'" } */ + __analyzer_dump_escaped (); /* { dg-warning "escaped: 2: 'local_1', 'only_used_by_test_1'" "" { target c } } */ + /* { dg-warning "escaped: 2: 'int local_1', 'int only_used_by_test_1'" "" { target c++ } .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/expect-1.c b/gcc/testsuite/c-c++-common/analyzer/expect-1.c index e538f77..c2f72b4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/expect-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/expect-1.c @@ -1,4 +1,4 @@ -#define NULL ((void*)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" void *test_1 (void) { diff --git a/gcc/testsuite/gcc.dg/analyzer/fgets-1.c b/gcc/testsuite/c-c++-common/analyzer/fgets-1.c index e93d24c..e67bb18 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fgets-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/fgets-1.c @@ -1,6 +1,6 @@ /* { dg-do "compile" } */ -#define NULL ((void *) 0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef struct _IO_FILE FILE; extern char *fgets(char *__restrict __s, int __n, diff --git a/gcc/testsuite/c-c++-common/analyzer/file-pr58237-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/file-pr58237-noexcept.c new file mode 100644 index 0000000..cdbbe00 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/file-pr58237-noexcept.c @@ -0,0 +1,82 @@ +/* { dg-additional-options "-fno-exceptions" } */ +typedef struct FILE FILE; + +FILE* fopen (const char*, const char*); +int fclose (FILE*); +char *fgets (char *, int, FILE *); + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +void f0(const char *str) +{ + FILE * fp = fopen(str, "r"); /* { dg-message "opened here" } */ + // ideally warning should be located at the end of the function + char buf[10]; + fgets(buf, 10, fp); +} /* { dg-warning "leak of FILE 'fp'" } */ + +void f1(const char *str) +{ + FILE * fp = fopen(str, "r"); /* { dg-message "opened here" } */ + // ideally warning should be located at the end of the function + char buf[10]; + + while (fgets(buf, 10, fp) != NULL) + { + /* Do something with buf */ + } +} /* { dg-warning "leak of FILE 'fp'" } */ + +void f2(const char *str, int flag) +{ + FILE * fp = fopen(str, "r"); /* { dg-message "opened here" } */ + // ideally warning should be located at the end of the function + char buf[10]; + + while (fgets(buf, 10, fp) != NULL) + { + /* Do something with buf */ + } + if (flag) /* { dg-message "when 'flag == 0'" } */ + fclose(fp); +} /* { dg-warning "leak of FILE 'fp'" } */ + +extern void called_by_f3( FILE * fp); + +void f3(const char *str) +{ + FILE * fp = fopen(str, "r"); + char buf[10]; + + while (fgets(buf, 10, fp) != NULL) + { + /* Do something with buf */ + } + /* Not sure if fclose executed by called_by_f3 or not. Say nothing */ + called_by_f3(fp); +} + +void f4(const char *str) +{ + FILE * fp = fopen(str, "r"); + char buf[10]; + + while (fgets(buf, 10, fp) != NULL) + { + /* Do something with buf */ + } + /* Nothing to say here. */ + fclose(fp); +} + +int main(int argc, const char * argv[]) +{ + FILE * fp = fopen(argv[0], "r"); + char buf[10]; + + while (fgets(buf, 10, fp) != NULL) + { + /* Do something with buf */ + } + /* Nothing to say here, because we are in main. */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c b/gcc/testsuite/c-c++-common/analyzer/file-uninit-1.c index 0f8ac54..0f8ac54 100644 --- a/gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/file-uninit-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/fileno-1.c b/gcc/testsuite/c-c++-common/analyzer/fileno-1.c index d34e51a..d34e51a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fileno-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/fileno-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/first-field-1.c b/gcc/testsuite/c-c++-common/analyzer/first-field-1.c index 8b71e1a..c11707d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/first-field-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/first-field-1.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef struct base_obj { diff --git a/gcc/testsuite/gcc.dg/analyzer/first-field-2.c b/gcc/testsuite/c-c++-common/analyzer/first-field-2.c index 2fb98d3..8661e6e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/first-field-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/first-field-2.c @@ -3,7 +3,7 @@ #include <stdlib.h> #include <string.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef struct base_obj base_obj; typedef struct string_obj string_obj; diff --git a/gcc/testsuite/gcc.dg/analyzer/flex-with-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c index 45edacf..45edacf 100644 --- a/gcc/testsuite/gcc.dg/analyzer/flex-with-call-summaries.c +++ b/gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c diff --git a/gcc/testsuite/gcc.dg/analyzer/flex-without-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c index 5b4a986..5369f76 100644 --- a/gcc/testsuite/gcc.dg/analyzer/flex-without-call-summaries.c +++ b/gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c @@ -878,7 +878,8 @@ static int yy_get_next_buffer (void) else b->yy_buf_size *= 2; - b->yy_ch_buf = (char *) /* { dg-warning "leak of '\\*b.yy_ch_buf'" } */ + b->yy_ch_buf = (char *) /* { dg-warning "leak of '\\*b.yy_ch_buf'" "" { target c } } */ + /* { dg-warning "leak of '\\*b.yy_buffer_state::yy_ch_buf'" "" { target c++ } .-1 } */ /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) ); diff --git a/gcc/testsuite/gcc.dg/analyzer/flexible-array-member-1.c b/gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c index 2df085a..82dbcec 100644 --- a/gcc/testsuite/gcc.dg/analyzer/flexible-array-member-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/flexible-array-member-1.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <string.h> +#include "../../gcc.dg/analyzer/analyzer-decls.h" struct str { size_t len; @@ -9,7 +10,7 @@ struct str { struct str * test_const_size (void) { - struct str *str = malloc(sizeof(str) + 10); + struct str *str = (struct str *) malloc(sizeof(str) + 10); if (str) { str->len = 10; memset(str->data, 'x', 10); @@ -22,11 +23,12 @@ struct str * test_const_size_oob_1 (void) { /* Forgetting to add space for the trailing array. */ - struct str *str = malloc(sizeof(str)); + struct str *str = (struct str *) malloc(sizeof(str)); if (str) { str->len = 10; memset(str->data, 'x', 10); /* { dg-warning "heap-based buffer overflow" "Wanalyzer-out-of-bounds" } */ - /* { dg-warning "'memset' writing 10 bytes into a region of size 0 overflows the destination" "Wstringop-overflow" { target *-*-* } .-1 } */ + /* { dg-warning "'memset' writing 10 bytes into a region of size 0 overflows the destination" "Wstringop-overflow" { target c } .-1 } */ + /* { dg-warning "'void\\* memset\\(void\\*, int, size_t\\)' writing 10 bytes into a region of size 0 overflows the destination" "Wstringop-overflow" { target c++ } .-2 } */ return str; } return NULL; @@ -35,12 +37,14 @@ test_const_size_oob_1 (void) struct str * test_const_size_oob_2 (void) { - struct str *str = malloc(sizeof(str) + 10); + struct str *str = (struct str *) malloc(sizeof(str) + 10); if (str) { str->len = 10; /* Using the wrong size here. */ memset(str->data, 'x', 11); /* { dg-warning "heap-based buffer overflow" "Wanalyzer-out-of-bounds" } */ - /* { dg-warning "'memset' writing 11 bytes into a region of size 10 overflows the destination" "Wstringop-overflow" { target *-*-* } .-1 } */ + /* { dg-warning "'memset' writing 11 bytes into a region of size 10 overflows the destination" "Wstringop-overflow" { target c } .-1 } */ + /* { dg-warning "'void\\* memset\\(void\\*, int, size_t\\)' writing 11 bytes into a region of size 10 overflows the destination" "Wstringop-overflow" { target c++ } .-2 } */ + return str; } return NULL; @@ -49,7 +53,7 @@ test_const_size_oob_2 (void) struct str * test_symbolic_size (size_t len) { - struct str *str = malloc(sizeof(str) + len); + struct str *str = (struct str *) malloc(sizeof(str) + len); if (str) { str->len = len; memset(str->data, 'x', len); @@ -62,7 +66,7 @@ struct str * test_symbolic_size_oob (size_t len) { /* Forgetting to add space for the trailing array. */ - struct str *str = malloc(sizeof(str)); + struct str *str = (struct str *) malloc(sizeof(str)); if (str) { str->len = len; memset(str->data, 'x', len); /* { dg-warning "heap-based buffer overflow" "PR analyzer/98247" { xfail *-*-* } } */ @@ -75,7 +79,7 @@ test_symbolic_size_oob (size_t len) struct str * test_symbolic_size_with_terminator (size_t len) { - struct str *str = malloc(sizeof(str) + len + 1); + struct str *str = (struct str *) malloc(sizeof(str) + len + 1); if (str) { str->len = len; memset(str->data, 'x', len); @@ -89,7 +93,7 @@ struct str * test_symbolic_size_with_terminator_oob (size_t len) { /* Forgetting to add 1 for the terminator. */ - struct str *str = malloc(sizeof(str) + len); + struct str *str = (struct str *) malloc(sizeof(str) + len); if (str) { str->len = len; memset(str->data, 'x', len); diff --git a/gcc/testsuite/gcc.dg/analyzer/fold-string-to-char.c b/gcc/testsuite/c-c++-common/analyzer/fold-string-to-char.c index 4613921..4eb08c0 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fold-string-to-char.c +++ b/gcc/testsuite/c-c++-common/analyzer/fold-string-to-char.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test_1 (void) { diff --git a/gcc/testsuite/c-c++-common/analyzer/fopen-2.c b/gcc/testsuite/c-c++-common/analyzer/fopen-2.c new file mode 100644 index 0000000..82087f2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/fopen-2.c @@ -0,0 +1,52 @@ +typedef struct FILE FILE; +FILE *fopen (const char *pathname, const char *mode); +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +FILE * +test_passthrough (const char *pathname, const char *mode) +{ + return fopen (pathname, mode); +} + +FILE * +test_null_pathname (const char *pathname, const char *mode) +{ + return fopen (NULL, mode); +} + +FILE * +test_null_mode (const char *pathname) +{ + return fopen (pathname, NULL); +} + +FILE * +test_simple_r (void) +{ + return fopen ("foo.txt", "r"); +} + +FILE * +test_swapped_args (void) +{ + return fopen ("r", "foo.txt"); /* TODO: would be nice to detect this. */ +} + +FILE * +test_uninitialized_pathname (const char *mode) +{ + char buf[10]; + return fopen (buf, mode); /* { dg-warning "use of uninitialized value 'buf\\\[0\\\]'" } */ + /* { dg-message "while looking for null terminator for argument 1 \\('&buf'\\) of 'fopen'..." "event" { target c } .-1 } */ + /* { dg-message "while looking for null terminator for argument 1 \\('& buf'\\) of 'FILE\\* fopen\\(const char\\*, const char\\*\\)'..." "event" { target c++ } .-2 } */ +} + +FILE * +test_uninitialized_mode (const char *filename) +{ + char buf[10]; + return fopen (filename, buf); /* { dg-warning "use of uninitialized value 'buf\\\[0\\\]'" } */ + /* { dg-message "while looking for null terminator for argument 2 \\('&buf'\\) of 'fopen'..." "event" { target c } .-1 } */ + /* { dg-message "while looking for null terminator for argument 2 \\('& buf'\\) of 'FILE\\* fopen\\(const char\\*, const char\\*\\)'..." "event" { target c++ } .-2 } */ +} + diff --git a/gcc/testsuite/gcc.dg/analyzer/fread-1.c b/gcc/testsuite/c-c++-common/analyzer/fread-1.c index 593cb7f..593cb7f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fread-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/fread-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/fread-2.c b/gcc/testsuite/c-c++-common/analyzer/fread-2.c index 02a5e31..d74d055 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fread-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/fread-2.c @@ -1,6 +1,6 @@ /* { dg-additional-options "-fdump-analyzer-untracked" } */ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" struct S { diff --git a/gcc/testsuite/gcc.dg/analyzer/fread-pr108661.c b/gcc/testsuite/c-c++-common/analyzer/fread-pr108661.c index b51cf41..b51cf41 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fread-pr108661.c +++ b/gcc/testsuite/c-c++-common/analyzer/fread-pr108661.c diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-1.c b/gcc/testsuite/c-c++-common/analyzer/function-ptr-1.c index 38c3e59..38c3e59 100644 --- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/function-ptr-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c b/gcc/testsuite/c-c++-common/analyzer/function-ptr-2.c index fd25e3b..0a1e845 100644 --- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/function-ptr-2.c @@ -1,5 +1,5 @@ #include <stdlib.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef void (*fn_ptr_t) (void *); diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-3.c b/gcc/testsuite/c-c++-common/analyzer/function-ptr-3.c index 348ee4a..348ee4a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/function-ptr-3.c diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c b/gcc/testsuite/c-c++-common/analyzer/function-ptr-4.c index 016351a..016351a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c +++ b/gcc/testsuite/c-c++-common/analyzer/function-ptr-4.c diff --git a/gcc/testsuite/gcc.dg/analyzer/getc-1.c b/gcc/testsuite/c-c++-common/analyzer/getc-1.c index 04896ce..04896ce 100644 --- a/gcc/testsuite/gcc.dg/analyzer/getc-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/getc-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/getchar-1.c b/gcc/testsuite/c-c++-common/analyzer/getchar-1.c index 0cc984b..157877d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/getchar-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/getchar-1.c @@ -1,7 +1,7 @@ /* { dg-skip-if "" { powerpc*-*-aix* } } */ #include <stdio.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" int test_1 (void) { diff --git a/gcc/testsuite/gcc.dg/analyzer/gzio-2.c b/gcc/testsuite/c-c++-common/analyzer/gzio-2.c index 855ecc8..855ecc8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/gzio-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/gzio-2.c diff --git a/gcc/testsuite/gcc.dg/analyzer/gzio-3.c b/gcc/testsuite/c-c++-common/analyzer/gzio-3.c index 4266832..4266832 100644 --- a/gcc/testsuite/gcc.dg/analyzer/gzio-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/gzio-3.c diff --git a/gcc/testsuite/gcc.dg/analyzer/gzio-3a.c b/gcc/testsuite/c-c++-common/analyzer/gzio-3a.c index faf86fa..faf86fa 100644 --- a/gcc/testsuite/gcc.dg/analyzer/gzio-3a.c +++ b/gcc/testsuite/c-c++-common/analyzer/gzio-3a.c diff --git a/gcc/testsuite/gcc.dg/analyzer/gzio.c b/gcc/testsuite/c-c++-common/analyzer/gzio.c index 54efa77..54efa77 100644 --- a/gcc/testsuite/gcc.dg/analyzer/gzio.c +++ b/gcc/testsuite/c-c++-common/analyzer/gzio.c diff --git a/gcc/testsuite/gcc.dg/analyzer/imprecise-floating-point-1.c b/gcc/testsuite/c-c++-common/analyzer/imprecise-floating-point-1.c index 7fe09fb..cbe2658 100644 --- a/gcc/testsuite/gcc.dg/analyzer/imprecise-floating-point-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/imprecise-floating-point-1.c @@ -10,7 +10,7 @@ void test_1 (float f) { - int *ptr = malloc (sizeof (int) * f); /* { dg-line test_1 } */ + int *ptr = (int *)malloc (sizeof (int) * f); /* { dg-line test_1 } */ free (ptr); /* { dg-warning "use of floating-point arithmetic here might yield unexpected results" "warning" { target *-*-* } test_1 } */ @@ -20,11 +20,11 @@ void test_1 (float f) void test_2 (int n) { - int *ptr = malloc (n * 3.1); /* { dg-line test_2 } */ + int *ptr = (int *)malloc (n * 3.1); /* { dg-line test_2 } */ free (ptr); /* { dg-warning "use of floating-point arithmetic here might yield unexpected results" "warning" { target *-*-* } test_2 } */ - /* { dg-message "operand '\(\\d|e|f|\\.|\\+|\)+' is of type 'double'" "note" { target *-*-* } test_2 } */ + /* { dg-message "operand '\(\\d|e|f|l|\\.|\\+|\)+' is of type '\(long \)?double'" "note" { target *-*-* } test_2 } */ /* { dg-message "only use operands of an integer type inside the size argument" "note" { target *-*-* } test_2 } */ } @@ -45,17 +45,17 @@ void test_3 (float f) void test_4 (int n) { - int *ptr = calloc(1.7 * n, sizeof (int)); /* { dg-line test_4 } */ + int *ptr = (int *)calloc(1.7 * n, sizeof (int)); /* { dg-line test_4 } */ free (ptr); /* { dg-warning "use of floating-point arithmetic here might yield unexpected results" "warning" { target *-*-* } test_4 } */ - /* { dg-message "operand '\(\\d|e|f|\\.|\\+|\)+' is of type 'double'" "note" { target *-*-* } test_4 } */ + /* { dg-message "operand '\(\\d|e|f|l|\\.|\\+|\)+' is of type '\(long \)?double'" "note" { target *-*-* } test_4 } */ /* { dg-message "only use operands of an integer type inside the size argument" "note" { target *-*-* } test_4 } */ } int test_5 (float f) { - int *ptr = __builtin_alloca (sizeof (int) * f); /* { dg-line test_5 } */ + int *ptr = (int *)__builtin_alloca (sizeof (int) * f); /* { dg-line test_5 } */ *ptr = 4; return *ptr; @@ -66,7 +66,7 @@ int test_5 (float f) int test_6 (float f) { - int *ptr = __builtin_alloca (1.7f * f * 2.3f); /* { dg-line test_6 } */ + int *ptr = (int *)__builtin_alloca (1.7f * f * 2.3f); /* { dg-line test_6 } */ *ptr = 4; return *ptr; diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-2.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-2.c index f0ab130..f0ab130 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-2.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-3.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c index 68c4fa3..68c4fa3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-limited-buggy.c index a71b902..a71b902 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-limited-buggy.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-limited.c index 55326d2..55326d2 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-limited.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-limited.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-unlimited-buggy.c index 7ed1a2b..7ed1a2b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-unlimited-buggy.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-unlimited.c index bdb54a3..bdb54a3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-4-unlimited.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-4-unlimited.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-5.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-5.c index bf20639..bf20639 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-5.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-5.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-alloca.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-alloca.c index 87727e8..87727e8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-alloca.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-alloca.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-inlining.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-inlining.c index c885c92..c885c92 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-inlining.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-inlining.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-1.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-multiline-1.c index e236dd4..21f3894 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-multiline-1.c @@ -38,4 +38,33 @@ void foo (int flag) | (5) recursive entry to 'foo'; previously entered at (1) | (6) apparently infinite recursion | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + foo (flag); + ~~~~^~~~~~ + 'void foo(int)': events 1-4 (depth 1) + | + | void foo (int flag) + | ^~~ + | | + | (1) initial entry to 'foo' + | + | if (flag) + | ~~ + | | + | (2) following 'true' branch (when 'flag != 0')... + | foo (flag); + | ~~~~~~~~~~ + | | + | (3) ...to here + | (4) calling 'foo' from 'foo' + | + +--> 'void foo(int)': events 5-6 (depth 2) + | + | void foo (int flag) + | ^~~ + | | + | (5) recursive entry to 'foo'; previously entered at (1) + | (6) apparently infinite recursion + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-2.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-multiline-2.c index 2c69dd5..be4fb6c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-multiline-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-multiline-2.c @@ -52,7 +52,43 @@ void mutual_2 (void) | (5) recursive entry to 'mutual_2'; previously entered at (1) | (6) apparently infinite chain of mutually-recursive function calls, consuming 2 stack frames per recursion | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + mutual_2 (); + ~~~~~~~~~^~ + 'void mutual_2()': events 1-2 (depth 1) + | + | void mutual_2 (void) + | ^~~~~~~~ + | | + | (1) initial entry to 'mutual_2' + | + | mutual_1 (); + | ~~~~~~~~~~~ + | | + | (2) calling 'mutual_1' from 'mutual_2' + | + +--> 'void mutual_1()': events 3-4 (depth 2) + | + | void mutual_1 (void) + | ^~~~~~~~ + | | + | (3) entry to 'mutual_1' + | + | mutual_2 (); + | ~~~~~~~~~~~ + | | + | (4) calling 'mutual_2' from 'mutual_1' + | + +--> 'void mutual_2()': events 5-6 (depth 3) + | + | void mutual_2 (void) + | ^~~~~~~~ + | | + | (5) recursive entry to 'mutual_2'; previously entered at (1) + | (6) apparently infinite chain of mutually-recursive function calls, consuming 2 stack frames per recursion + | + { dg-end-multiline-output "" { target c++ } } */ /* { dg-begin-multiline-output "" } @@ -90,4 +126,40 @@ void mutual_2 (void) | (5) recursive entry to 'mutual_1'; previously entered at (1) | (6) apparently infinite chain of mutually-recursive function calls, consuming 2 stack frames per recursion | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + mutual_1 (); + ~~~~~~~~~^~ + 'void mutual_1()': events 1-2 (depth 1) + | + | void mutual_1 (void) + | ^~~~~~~~ + | | + | (1) initial entry to 'mutual_1' + | + | mutual_2 (); + | ~~~~~~~~~~~ + | | + | (2) calling 'mutual_2' from 'mutual_1' + | + +--> 'void mutual_2()': events 3-4 (depth 2) + | + | void mutual_2 (void) + | ^~~~~~~~ + | | + | (3) entry to 'mutual_2' + | + | mutual_1 (); + | ~~~~~~~~~~~ + | | + | (4) calling 'mutual_1' from 'mutual_2' + | + +--> 'void mutual_1()': events 5-6 (depth 3) + | + | void mutual_1 (void) + | ^~~~~~~~ + | | + | (5) recursive entry to 'mutual_1'; previously entered at (1) + | (6) apparently infinite chain of mutually-recursive function calls, consuming 2 stack frames per recursion + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108935-1.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108935-1.c index 83efe9b..83efe9b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108935-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108935-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108935-1a.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108935-1a.c index b3c4920..b3c4920 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108935-1a.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108935-1a.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108935-2.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108935-2.c index c46f1f8..c46f1f8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108935-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108935-2.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-variadic.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-variadic.c index eafbeba..eafbeba 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-variadic.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-variadic.c diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion.c index 6b7d25c..6b7d25c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion.c +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion.c diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-1-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-1-multiline.c index 79621f1..cda5a7d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-1-multiline.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-1-multiline.c @@ -53,4 +53,43 @@ void bar (void *q) | | | (5) second 'free' here; first 'free' was at (3) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ~~~~~~~~~~~~~~~^~~ + 'void bar(void*)': events 1-2 (depth 1) + | + | void bar (void *q) + | ^~~ + | | + | (1) entry to 'bar' + | + | foo (q); + | ~ + | | + | (2) inlined call to 'foo' from 'bar' + | + +--> 'void foo(void*)': event 3 (depth 2) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (3) first 'free' here + | + <------+ + | + 'void bar(void*)': event 4 (depth 1) + | + | foo (q); + | ^ + | | + | (4) inlined call to 'foo' from 'bar' + | + +--> 'void foo(void*)': event 5 (depth 2) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (5) second 'free' here; first 'free' was at (3) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-1-no-undo.c b/gcc/testsuite/c-c++-common/analyzer/inlining-1-no-undo.c index bad0f68..d0d1b82 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-1-no-undo.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-1-no-undo.c @@ -7,8 +7,10 @@ void foo (void *p) { __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ - /* { dg-message "\\(1\\) first 'free' here \\(fndecl 'bar', depth 1\\)" "1st free message" { target *-*-* } .-1 } */ - /* { dg-message "\\(2\\) second 'free' here; first 'free' was at \\(1\\) \\(fndecl 'bar', depth 1\\)" "2nd free message" { target *-*-* } .-2 } */ + /* { dg-message "\\(1\\) first 'free' here \\(fndecl 'bar', depth 1\\)" "1st free message" { target c } .-1 } */ + /* { dg-message "\\(1\\) first 'free' here \\(fndecl 'void bar\\(void\\*\\)', depth 1\\)" "1st free message" { target c++ } .-2 } */ + /* { dg-message "\\(2\\) second 'free' here; first 'free' was at \\(1\\) \\(fndecl 'bar', depth 1\\)" "2nd free message" { target c } .-3 } */ + /* { dg-message "\\(2\\) second 'free' here; first 'free' was at \\(1\\) \\(fndecl 'void bar\\(void\\*\\)', depth 1\\)" "2nd free message" { target c++ } .-4 } */ } void bar (void *q) diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-1.c b/gcc/testsuite/c-c++-common/analyzer/inlining-1.c new file mode 100644 index 0000000..ed33e78 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-1.c @@ -0,0 +1,22 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +void foo (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ + /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'foo', depth 2\\)" "1st free message" { target c } .-1 } */ + /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'void foo\\(void\\*\\)', depth 2\\)" "1st free message" { target c++ } .-2 } */ + /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'foo', depth 2\\)" "2nd free message" { target c } .-3 } */ + /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'void foo\\(void\\*\\)', depth 2\\)" "2nd free message" { target c++ } .-4 } */ +} + +void bar (void *q) /* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'bar', depth 1\\)" "" { target c } } */ +/* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'void bar\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +{ + foo (q); /* { dg-message "\\(2\\) inlined call to 'foo' from 'bar' \\(fndecl 'bar', depth 1\\)" "" { target c } } */ + /* { dg-message "\\(2\\) inlined call to 'foo' from 'bar' \\(fndecl 'void bar\\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ + foo (q); /* { dg-message "\\(4\\) inlined call to 'foo' from 'bar' \\(fndecl 'bar', depth 1\\)" "" { target c } } */ + /* { dg-message "\\(4\\) inlined call to 'foo' from 'bar' \\(fndecl 'void bar\\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-2-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-2-multiline.c index 0a006b3..7a259a8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-2-multiline.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-2-multiline.c @@ -43,4 +43,32 @@ void bar (void *q) | | | (4) second 'free' here; first 'free' was at (3) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ~~~~~~~~~~~~~~~^~~ + 'void bar(void*)': events 1-2 (depth 1) + | + | void bar (void *q) + | ^~~ + | | + | (1) entry to 'bar' + | + | __analyzer_foo (q); + | ~ + | | + | (2) inlined call to '__analyzer_foo' from 'bar' + | + +--> 'void __analyzer_foo(void*)': events 3-4 (depth 2) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (3) first 'free' here + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~~~~ + | | + | (4) second 'free' here; first 'free' was at (3) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-2.c b/gcc/testsuite/c-c++-common/analyzer/inlining-2.c new file mode 100644 index 0000000..1561bee --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-2.c @@ -0,0 +1,21 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +static void __analyzer_foo (void *p) +{ + __builtin_free (p); /* { dg-message "\\(3\\) first 'free' here \\(fndecl '__analyzer_foo', depth 2\\)" "1st free message" { target c } } */ + /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'void __analyzer_foo\\(void\\*\\)', depth 2\\)" "1st free message" { target c++ } .-1 } */ + + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ + /* { dg-message "\\(4\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl '__analyzer_foo', depth 2\\)" "2nd free message" { target c } .-1 } */ + /* { dg-message "\\(4\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'void __analyzer_foo\\(void\\*\\)', depth 2\\)" "2nd free message" { target c++ } .-2 } */ +} + +void bar (void *q) /* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'bar', depth 1\\)" "" { target c } } */ +/* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'void bar\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +{ + __analyzer_foo (q); /* { dg-message "\\(2\\) inlined call to '__analyzer_foo' from 'bar' \\(fndecl 'bar', depth 1\\)" "" { target c } } */ + /* { dg-message "\\(2\\) inlined call to '__analyzer_foo' from 'bar' \\(fndecl 'void bar\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-5-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-5-multiline.c index 21b8fb9..8fefe38 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-5-multiline.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-5-multiline.c @@ -56,4 +56,38 @@ outer (void *r) | | | (5) second 'free' here; first 'free' was at (3) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ~~~~~~~~~~~~~~~^~~ + 'void outer(void*)': events 1-2 (depth 1) + | + | outer (void *r) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | middle (r); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'void middle(void*)': events 3-4 (depth 2) + | + | __builtin_free (q); + | ~~~~~~~~~~~~~~~^~~ + | | + | (3) first 'free' here + | inner (q); + | ~ + | | + | (4) inlined call to 'inner' from 'middle' + | + +--> 'void inner(void*)': event 5 (depth 3) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (5) second 'free' here; first 'free' was at (3) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-5.c b/gcc/testsuite/c-c++-common/analyzer/inlining-5.c new file mode 100644 index 0000000..7b08c4b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-5.c @@ -0,0 +1,29 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +static inline void +inner (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'r'" } */ + /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'inner', depth 3\\)" "2nd free message" { target c } .-1 } */ + /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'void inner\\(void\\*\\)', depth 3\\)" "2nd free message" { target c++ } .-2 } */ +} + +static inline void +middle (void *q) +{ + __builtin_free (q); /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'middle', depth 2\\)" "1st free message" { target c } } */ + /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'void middle\\(void\\*\\)', depth 2\\)" "1st free message" { target c++ } .-1 } */ + inner (q); /* { dg-message "\\(4\\) inlined call to 'inner' from 'middle' \\(fndecl 'middle', depth 2\\)" "" { target c } } */ + /* { dg-message "\\(4\\) inlined call to 'inner' from 'middle' \\(fndecl 'void middle\\(void\\*\\)', depth 2\\)" "" { target c++ } .-1 } */ +} + +void +outer (void *r) /* { dg-message "\\(1\\) entry to 'outer' \\(fndecl 'outer', depth 1\\)" "" { target c } } */ +/* { dg-message "\\(1\\) entry to 'outer' \\(fndecl 'void outer\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +{ + middle (r); /* { dg-message "\\(2\\) inlined call to 'middle' from 'outer' \\(fndecl 'outer', depth 1\\)" "" { target c } } */ + /* { dg-message "\\(2\\) inlined call to 'middle' from 'outer' \\(fndecl 'void outer\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-6-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-6-multiline.c index 9cec614..3fbf854 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-6-multiline.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-6-multiline.c @@ -61,4 +61,43 @@ outer (void *r) | | | (5) second 'free' here; first 'free' was at (4) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + __builtin_free (q); + ~~~~~~~~~~~~~~~^~~ + 'void outer(void*)': events 1-2 (depth 1) + | + | outer (void *r) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | middle (r); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'void middle(void*)': event 3 (depth 2) + | + | inner (q); + | ^ + | | + | (3) inlined call to 'inner' from 'middle' + | + +--> 'void inner(void*)': event 4 (depth 3) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (4) first 'free' here + | + <------+ + | + 'void middle(void*)': event 5 (depth 2) + | + | __builtin_free (q); + | ~~~~~~~~~~~~~~~^~~ + | | + | (5) second 'free' here; first 'free' was at (4) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-6.c b/gcc/testsuite/c-c++-common/analyzer/inlining-6.c index e19e85a..e19e85a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-6.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-6.c diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-7-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-7-multiline.c index 956c6b9..78fe4d4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-7-multiline.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-7-multiline.c @@ -125,4 +125,85 @@ depth_1 (void *p1) | | | (11) second 'free' here; first 'free' was at (7) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ~~~~~~~~~~~~~~~^~~ + 'void depth_1(void*)': events 1-2 (depth 1) + | + | depth_1 (void *p1) + | ^~~~~~~ + | | + | (1) entry to 'depth_1' + | + | depth_2 (p1); + | ~ + | | + | (2) inlined call to 'depth_2' from 'depth_1' + | + +--> 'void depth_2(void*)': event 3 (depth 2) + | + | depth_3 (p2); + | ^ + | | + | (3) inlined call to 'depth_3' from 'depth_2' + | + +--> 'void depth_3(void*)': event 4 (depth 3) + | + | depth_4 (p3); + | ^ + | | + | (4) inlined call to 'depth_4' from 'depth_3' + | + +--> 'void depth_4(void*)': event 5 (depth 4) + | + | depth_5 (p4); + | ^ + | | + | (5) inlined call to 'depth_5' from 'depth_4' + | + +--> 'void depth_5(void*)': event 6 (depth 5) + | + | depth_6 (p5); + | ^ + | | + | (6) inlined call to 'depth_6' from 'depth_5' + | + +--> 'void depth_6(void*)': event 7 (depth 6) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (7) first 'free' here + | + <--------------------+ + | + 'void depth_3(void*)': event 8 (depth 3) + | + | depth_4 (p3); + | ^ + | | + | (8) inlined call to 'depth_4' from 'depth_3' + | + +--> 'void depth_4(void*)': event 9 (depth 4) + | + | depth_5 (p4); + | ^ + | | + | (9) inlined call to 'depth_5' from 'depth_4' + | + +--> 'void depth_5(void*)': event 10 (depth 5) + | + | depth_6 (p5); + | ^ + | | + | (10) inlined call to 'depth_6' from 'depth_5' + | + +--> 'void depth_6(void*)': event 11 (depth 6) + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~^~~ + | | + | (11) second 'free' here; first 'free' was at (7) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-7.c b/gcc/testsuite/c-c++-common/analyzer/inlining-7.c new file mode 100644 index 0000000..960944f --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-7.c @@ -0,0 +1,60 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +/* We want the reconstructed call/return hierarchy to show + that two calls happen at depth_3, without any spurious events + popping the stack back any further. */ + +static inline void +depth_6 (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'p1'" "warning" } */ + /* { dg-message "\\(7\\) first 'free' here \\(fndecl 'depth_6', depth 6\\)" "1st free message" { target c } .-1 } */ + /* { dg-message "\\(7\\) first 'free' here \\(fndecl 'void depth_6\\(void\\*\\)', depth 6\\)" "1st free message" { target c++ } .-2 } */ + /* { dg-message "\\(11\\) second 'free' here; first 'free' was at \\(7\\) \\(fndecl 'depth_6', depth 6\\)" "2nd free message" { target c } .-3 } */ + /* { dg-message "\\(11\\) second 'free' here; first 'free' was at \\(7\\) \\(fndecl 'void depth_6\\(void\\*\\)', depth 6\\)" "2nd free message" { target c++ } .-4 } */ +} + +static inline void +depth_5 (void *p5) +{ + depth_6 (p5); /* { dg-message "\\(6\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'depth_5', depth 5\\)" "event 6" { target c } } */ + /* { dg-message "\\(6\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'void depth_5\\(void\\*\\)', depth 5\\)" "event 6" { target c++ } .-1 } */ + /* { dg-message "\\(10\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'depth_5', depth 5\\)" "event 10" { target c } .-2 } */ + /* { dg-message "\\(10\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'void depth_5\\(void\\*\\)', depth 5\\)" "event 10" { target c++ } .-3 } */ +} + +static inline void +depth_4 (void *p4) +{ + depth_5 (p4); /* { dg-message "\\(5\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'depth_4', depth 4\\)" "event 5" { target c } } */ + /* { dg-message "\\(5\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'void depth_4\\(void\\*\\)', depth 4\\)" "event 5" { target c++ } .-1 } */ + /* { dg-message "\\(9\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'depth_4', depth 4\\)" "event 9" { target c } .-2 } */ + /* { dg-message "\\(9\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'void depth_4\\(void\\*\\)', depth 4\\)" "event 9" { target c++ } .-3 } */ +} + +static inline void +depth_3 (void *p3) +{ + depth_4 (p3); /* { dg-message "\\(4\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'depth_3', depth 3\\)" "" { target c } } */ + /* { dg-message "\\(4\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'void depth_3\\(void\\*\\)', depth 3\\)" "" { target c++ } .-1 } */ + depth_4 (p3); /* { dg-message "\\(8\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'depth_3', depth 3\\)" "" { target c } } */ + /* { dg-message "\\(8\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'void depth_3\\(void\\*\\)', depth 3\\)" "" { target c++ } .-1 } */ +} + +static inline void +depth_2 (void *p2) +{ + depth_3 (p2); /* { dg-message "\\(3\\) inlined call to 'depth_3' from 'depth_2' \\(fndecl 'depth_2', depth 2\\)" "" { target c } } */ + /* { dg-message "\\(3\\) inlined call to 'depth_3' from 'depth_2' \\(fndecl 'void depth_2\\(void\\*\\)', depth 2\\)" "" { target c++ } .-1 } */ +} + +void +depth_1 (void *p1) /* { dg-message "\\(1\\) entry to 'depth_1' \\(fndecl 'depth_1', depth 1\\)" "" { target c } } */ +/* { dg-message "\\(1\\) entry to 'depth_1' \\(fndecl 'void depth_1\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +{ + depth_2 (p1); /* { dg-message "\\(2\\) inlined call to 'depth_2' from 'depth_1' \\(fndecl 'depth_1', depth 1\\)" "" { target c } } */ + /* { dg-message "\\(2\\) inlined call to 'depth_2' from 'depth_1' \\(fndecl 'void depth_1\\(void\\*\\)', depth 1\\)" "" { target c++ } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c b/gcc/testsuite/c-c++-common/analyzer/invalid-shift-1.c index 08e5272..08e5272 100644 --- a/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/invalid-shift-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/isatty-1.c b/gcc/testsuite/c-c++-common/analyzer/isatty-1.c index 3bb12c0..c5d376d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/isatty-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/isatty-1.c @@ -2,7 +2,7 @@ /* { dg-skip-if "" { "avr-*-*" } } */ #include <errno.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern int isatty(int fd); extern int close(int fd); diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-2.c b/gcc/testsuite/c-c++-common/analyzer/leak-2.c index bba3e81..d12850c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/leak-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/leak-2.c @@ -1,8 +1,9 @@ #include <stdlib.h> +#include "../../gcc.dg/analyzer/analyzer-decls.h" void *ptr; -void *test (void) +void test (void) { ptr = malloc (1024); ptr = NULL; /* { dg-warning "leak of 'ptr'" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-3.c b/gcc/testsuite/c-c++-common/analyzer/leak-3.c index d11cc03..d11cc03 100644 --- a/gcc/testsuite/gcc.dg/analyzer/leak-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/leak-3.c diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-4.c b/gcc/testsuite/c-c++-common/analyzer/leak-4.c index 75090e6..ba5f2d2 100644 --- a/gcc/testsuite/gcc.dg/analyzer/leak-4.c +++ b/gcc/testsuite/c-c++-common/analyzer/leak-4.c @@ -11,7 +11,7 @@ struct s1 void test_1 (void) { - struct s1 *a = malloc (sizeof (struct s1)); + struct s1 *a = (struct s1 *) malloc (sizeof (struct s1)); if (!a) return; a->ptr = malloc (1024); /* { dg-message "allocated here" } */ @@ -32,25 +32,30 @@ void test_2a (void) { struct s2 arr[5]; arr[3].m_arr[4] = malloc (1024); /* { dg-message "allocated here" } */ -} /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[4\\\]'" } */ +} /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[4\\\]'" "" { target c } } */ +/* { dg-warning "leak of 'arr\\\[3\\\].s2::m_arr\\\[4\\\]'" "" { target c++ } .-1 } */ void test_2b (int i) { struct s2 arr[5]; arr[3].m_arr[i] = malloc (1024); /* { dg-message "allocated here" } */ -} /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[i\\\]'" } */ +} /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[i\\\]'" "" { target c } } */ +/* { dg-warning "leak of 'arr\\\[3\\\].s2::m_arr\\\[i\\\]'" "" { target c++ } .-1 } */ void test_2c (int i) { struct s2 arr[5]; arr[i].m_arr[4] = malloc (1024); /* { dg-message "allocated here" } */ -} /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[4\\\]'" } */ +} /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[4\\\]'" "" { target c } } */ +/* { dg-warning "leak of 'arr\\\[i\\\].s2::m_arr\\\[4\\\]'" "" { target c++ } .-1 } */ + void test_2d (int i, int j) { struct s2 arr[5]; arr[i].m_arr[j] = malloc (1024); /* { dg-message "allocated here" } */ -} /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[j\\\]'" } */ +} /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[j\\\]'" "" { target c } } */ +/* { dg-warning "leak of 'arr\\\[i\\\].s2::m_arr\\\[j\\\]'" "" { target c++ } .-1 } */ /* Example involving fields. */ @@ -63,9 +68,10 @@ struct s3 void test_3 (void) { - struct s3 *a = malloc (sizeof (struct s3)); - a->m_right = malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL 'a'" } */ - a->m_right->m_left = malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL '\\*a.m_right'" } */ + struct s3 *a = (struct s3 *) malloc (sizeof (struct s3)); + a->m_right = (struct s3 *) malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL 'a'" } */ + a->m_right->m_left = (struct s3 *) malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL '\\*a.m_right'" "" { target c } } */ + /* { dg-warning "dereference of possibly-NULL '\\*a.s3::m_right'" "" { target c++ } .-1 } */ } /* { dg-warning "leak of 'a'" "leak of a" } */ /* { dg-warning "leak of '<unknown>'" "leak of unknown" { target *-*-* } .-1 } */ /* TODO: rather than '<unknown>', we should print 'a->m_right' @@ -87,7 +93,7 @@ struct s4_sub static struct s4_sub * make_s4_sub (void) { - struct s4_sub *sub = malloc (sizeof (struct s4_sub)); /* { dg-message "allocated here" } */ + struct s4_sub *sub = (struct s4_sub *) malloc (sizeof (struct s4_sub)); /* { dg-message "allocated here" } */ if (!sub) return NULL; sub->m_buffer = malloc (1024); /* { dg-message "allocated here" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c b/gcc/testsuite/c-c++-common/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c index 0172c9b..1b65769 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c @@ -1,6 +1,6 @@ #include <stdlib.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" struct iter { @@ -45,7 +45,7 @@ void test(int n) struct iter *it = iter_new (0, n, 1); while (!iter_done_p (it)) { - __analyzer_eval (it->val < n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */ + __analyzer_eval (it->val < n); /* { dg-warning "TRUE" "true" } */ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1.c b/gcc/testsuite/c-c++-common/analyzer/loop-0-up-to-n-by-1.c index d49ed13..92ce3dc 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-0-up-to-n-by-1.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(int n) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-2.c b/gcc/testsuite/c-c++-common/analyzer/loop-2.c index f106722..274d508 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-2.c @@ -1,5 +1,5 @@ /* { dg-additional-options "-fno-analyzer-state-purge" } */ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" struct s { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-2a.c b/gcc/testsuite/c-c++-common/analyzer/loop-2a.c index 16b6449..212acf4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-2a.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-2a.c @@ -1,5 +1,5 @@ /* { dg-additional-options "-fno-analyzer-state-purge" } */ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" union u { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-3.c b/gcc/testsuite/c-c++-common/analyzer/loop-3.c index 0bcf707..0bcf707 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-3.c diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-4.c b/gcc/testsuite/c-c++-common/analyzer/loop-4.c index b66a345..dd3104e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-4.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-4.c @@ -1,6 +1,6 @@ /* Example of nested loops. */ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(void) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-n-down-to-1-by-1.c b/gcc/testsuite/c-c++-common/analyzer/loop-n-down-to-1-by-1.c index 553cd2f..1ab8abe 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-n-down-to-1-by-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-n-down-to-1-by-1.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(int n) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-1.c b/gcc/testsuite/c-c++-common/analyzer/loop-start-down-to-end-by-1.c index 3513bf4..092cc97 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-start-down-to-end-by-1.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(int start, int end, int step) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-step.c b/gcc/testsuite/c-c++-common/analyzer/loop-start-down-to-end-by-step.c index 2692c50..f929f7a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-step.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-start-down-to-end-by-step.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(int start, int end, int step) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-to-end-by-step.c b/gcc/testsuite/c-c++-common/analyzer/loop-start-to-end-by-step.c index 3fc1362..71d9619 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-start-to-end-by-step.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-start-to-end-by-step.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(int start, int end, int step) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-up-to-end-by-1.c b/gcc/testsuite/c-c++-common/analyzer/loop-start-up-to-end-by-1.c index 5e21890..629f592 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-start-up-to-end-by-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop-start-up-to-end-by-1.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(int start, int end) { diff --git a/gcc/testsuite/gcc.dg/analyzer/loop.c b/gcc/testsuite/c-c++-common/analyzer/loop.c index c4cfd88..33ac96c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop.c +++ b/gcc/testsuite/c-c++-common/analyzer/loop.c @@ -1,4 +1,4 @@ -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" void test(void) { diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-3.c b/gcc/testsuite/c-c++-common/analyzer/malloc-3.c index 5afb6b3..f4e647b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-3.c @@ -2,7 +2,8 @@ /* Don't complain about leaks due to exiting from "main". */ -void main (void) +int main (void) { void *p = malloc (1024); + return 0; } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-5.c b/gcc/testsuite/c-c++-common/analyzer/malloc-5.c index b75135f..3b2a452 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-5.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-5.c @@ -5,7 +5,7 @@ void test (void) void *p = malloc (sizeof (int)); if (!p) return; - int *q = p; + int *q = (int *) p; if (!q) return; free (q); diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-401-example.c b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-401-example.c index cfb5e86..cfb5e86 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-401-example.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-401-example.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-415-examples.c b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-415-examples.c index 51d878a..51d878a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-415-examples.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-415-examples.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-416-examples.c b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-416-examples.c index 3f5e5e2..3f5e5e2 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-416-examples.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-416-examples.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-590-examples.c b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-590-examples.c index 9434f2d..11ab017 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-CWE-590-examples.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-590-examples.c @@ -33,7 +33,8 @@ void foo_1(){ /* do something interesting with bar */ /* ... */ - free(bar); /* { dg-warning "'free' of '&bar' which points to memory on the stack" } */ + free(bar); /* { dg-warning "'free' of '&bar' which points to memory on the stack" "" { target c } } */ + /* { dg-warning "'free' of '& bar' which points to memory on the stack" "" { target c++ } .-1 } */ } record_t bar[MAX_SIZE]; //Global var @@ -41,5 +42,6 @@ void foo_2(){ /* do something interesting with bar */ /* ... */ - free(bar); /* { dg-warning "'free' of '&bar' which points to memory not on the heap" } */ + free(bar); /* { dg-warning "'free' of '&bar' which points to memory not on the heap" "" { target c } } */ + /* { dg-warning "'free' of '& bar' which points to memory not on the heap" "" { target c++ } .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c b/gcc/testsuite/c-c++-common/analyzer/malloc-callbacks.c index cf3927f..ccd6c01 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-callbacks.c @@ -54,16 +54,16 @@ void test_3 (void *ptr) int *test_4 (void) { allocator_t alloc_fn = get_malloc (); - int *ptr = alloc_fn (sizeof (int)); /* { dg-message "this call could return NULL" } */ + int *ptr = (int *) alloc_fn (sizeof (int)); /* { dg-message "this call could return NULL" } */ *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */ return ptr; } -int *test_5 (void) +void test_5 (void) { allocator_t alloc_fn = get_alloca (); deallocator_t dealloc_fn = get_free (); - int *ptr = alloc_fn (sizeof (int)); /* dg-message "region created on stack here" } */ + int *ptr = (int *) alloc_fn (sizeof (int)); /* dg-message "region created on stack here" } */ dealloc_fn (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack" } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-dce.c b/gcc/testsuite/c-c++-common/analyzer/malloc-dce.c index 1b4b878..1b4b878 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-dce.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-dce.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c b/gcc/testsuite/c-c++-common/analyzer/malloc-dedupe-1.c index 233ab48..233ab48 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-dedupe-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-in-loop.c b/gcc/testsuite/c-c++-common/analyzer/malloc-in-loop.c index a8c85a9..b107157 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-in-loop.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-in-loop.c @@ -1,5 +1,5 @@ #include <stdlib.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern void foo (int *); diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-1.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-1.c index ad536ce..ad536ce 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-1.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-11.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-11.c index b65ff91..6050103 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-11.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-11.c @@ -93,4 +93,70 @@ void test (void *ptr) | | (11) ...to here | | (12) second 'free' here; first 'free' was at (6) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (victim); + | ~~~~~^~~~~~~~ + 'void test(void*)': events 1-2 + | + | NN | void test (void *ptr) + | | ^~~~ + | | | + | | (1) entry to 'test' + |...... + | NN | may_call_free (ptr); + | | ~~~~~~~~~~~~~~~~~~~ + | | | + | | (2) calling 'may_call_free' from 'test' + | + +--> 'void may_call_free(void*)': events 3-6 + | + | NN | may_call_free (void *victim) + | | ^~~~~~~~~~~~~ + | | | + | | (3) entry to 'may_call_free' + | NN | { + | NN | if (some_condition ()) + | | ~~ + | | | + | | (4) following 'false' branch... + |...... + | NN | free (victim); + | | ~~~~~~~~~~~~~ + | | | + | | (5) ...to here + | | (6) first 'free' here + | + <------+ + | + 'void test(void*)': events 7-8 + | + | NN | may_call_free (ptr); + | | ~~~~~~~~~~~~~~^~~~~ + | | | + | | (7) returning to 'test' from 'may_call_free' + |...... + | NN | may_call_free (ptr); + | | ~~~~~~~~~~~~~~~~~~~ + | | | + | | (8) passing freed pointer 'ptr' in call to 'may_call_free' from 'test' + | + +--> 'void may_call_free(void*)': events 9-12 + | + | NN | may_call_free (void *victim) + | | ^~~~~~~~~~~~~ + | | | + | | (9) entry to 'may_call_free' + | NN | { + | NN | if (some_condition ()) + | | ~~ + | | | + | | (10) following 'false' branch... + |...... + | NN | free (victim); + | | ~~~~~~~~~~~~~ + | | | + | | (11) ...to here + | | (12) second 'free' here; first 'free' was at (6) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-2.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-2.c index 800dd63..800dd63 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-2.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-3.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-3.c index 3dcfae8..3dcfae8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-3.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-4.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-4.c index 82d50bd..bd03d60 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-4.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-4.c @@ -7,7 +7,7 @@ static void calls_free(int *q) void test(void *p) { - calls_free(p); + calls_free((int *) p); free(p); /* { dg-warning "double-'free' of 'p'" } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-5.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-5.c index c66ecb5..ca8e6a5 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-5.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-5.c @@ -2,7 +2,7 @@ static int *calls_malloc(void) { - return malloc(sizeof(int)); + return (int *) malloc(sizeof(int)); } int *test(void) diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-6.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-6.c index 62f8b55..62f8b55 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-6.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-6.c diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-7.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-7.c index 0742370..1fe70dd 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-7.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-7.c @@ -10,8 +10,8 @@ static void maybe_calls_free_1(int *q, int flag) void test_1(void *p) { - maybe_calls_free_1(p, 1); - maybe_calls_free_1(p, 1); + maybe_calls_free_1((int *) p, 1); + maybe_calls_free_1((int *) p, 1); } /**************************************************************************/ @@ -24,6 +24,6 @@ static void maybe_calls_free_2(int *q, int flag) void test_2(void *p) { - maybe_calls_free_2(p, 0); - maybe_calls_free_2(p, 0); + maybe_calls_free_2((int *) p, 0); + maybe_calls_free_2((int *) p, 0); } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c index 3200447..5bc8e57 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-ipa-8-unchecked.c @@ -64,4 +64,45 @@ make_boxed_int (int i) | | | | | (6) 'result' could be NULL: unchecked value from (4) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | result->i = i; + | ~~~~~~~~~~^~~ + 'boxed_int* make_boxed_int(int)': events 1-2 + | + | NN | make_boxed_int (int i) + | | ^~~~~~~~~~~~~~ + | | | + | | (1) entry to 'make_boxed_int' + | NN | { + | NN | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int)); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (2) calling 'wrapped_malloc' from 'make_boxed_int' + | + +--> 'void* wrapped_malloc(size_t)': events 3-4 + | + | NN | void *wrapped_malloc (size_t size) + | | ^~~~~~~~~~~~~~ + | | | + | | (3) entry to 'wrapped_malloc' + | NN | { + | NN | return malloc (size); + | | ~~~~~~~~~~~~~ + | | | + | | (4) this call could return NULL + | + <------+ + | + 'boxed_int* make_boxed_int(int)': events 5-6 + | + | NN | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int)); + | | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~ + | | | + | | (5) possible return of NULL to 'make_boxed_int' from 'wrapped_malloc' + | NN | result->i = i; + | | ~~~~~~~~~~~~~ + | | | + | | (6) 'result' could be NULL: unchecked value from (4) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c b/gcc/testsuite/c-c++-common/analyzer/malloc-macro-inline-events.c index 9134bb4..d00d076 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-macro-inline-events.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-macro-inline-events.c @@ -7,7 +7,7 @@ /* { dg-warning "double-'free' of 'ptr'" "" { target *-*-* } 2 } */ -int test (void *ptr) +void test (void *ptr) { WRAPPED_FREE (ptr); /* { dg-message "in expansion of macro 'WRAPPED_FREE'" } */ WRAPPED_FREE (ptr); /* { dg-message "in expansion of macro 'WRAPPED_FREE'" } */ @@ -37,5 +37,31 @@ int test (void *ptr) | NN | WRAPPED_FREE (ptr); | | ^~~~~~~~~~~~ | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ + /* { dg-begin-multiline-output "" } + NN | #define WRAPPED_FREE(PTR) free(PTR) + | ~~~~^~~~~ + NN | WRAPPED_FREE (ptr); + | ^~~~~~~~~~~~ + 'void test(void*)': event 1 + | + | + | NN | #define WRAPPED_FREE(PTR) free(PTR) + | | ~~~~^~~~~ + | | | + | | (1) first 'free' here + | NN | WRAPPED_FREE (ptr); + | | ^~~~~~~~~~~~ + | + 'void test(void*)': event 2 + | + | + | NN | #define WRAPPED_FREE(PTR) free(PTR) + | | ~~~~^~~~~ + | | | + | | (2) second 'free' here; first 'free' was at (1) + | NN | WRAPPED_FREE (ptr); + | | ^~~~~~~~~~~~ + | + { dg-end-multiline-output "" { target c++ } } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-macro-separate-events.c b/gcc/testsuite/c-c++-common/analyzer/malloc-macro-separate-events.c index c56419e..647b29c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-macro-separate-events.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-macro-separate-events.c @@ -8,7 +8,7 @@ /* { dg-message "first 'free' here" "1st free event" { target *-*-* } 2 } */ /* { dg-message "second 'free' here" "2nd free event" { target *-*-* } 2 } */ -int test (void *ptr) +void test (void *ptr) { WRAPPED_FREE (ptr); /* { dg-message "in expansion of macro 'WRAPPED_FREE'" } */ WRAPPED_FREE (ptr); /* { dg-message "in expansion of macro 'WRAPPED_FREE'" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-macro.h b/gcc/testsuite/c-c++-common/analyzer/malloc-macro.h index 8c05b40..8c05b40 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-macro.h +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-macro.h diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c new file mode 100644 index 0000000..f914ed6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c @@ -0,0 +1,435 @@ +/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fno-exceptions" } */ +/* { dg-enable-nn-line-numbers "" } */ + +#include <stdlib.h> + +void test_1 (void) +{ + void *ptr = malloc (1024); + free (ptr); + free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */ +} +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ^~~~~~~~~~ + 'test_1': events 1-3 + | + | NN | void *ptr = malloc (1024); + | | ^~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (2) first 'free' here + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (3) second 'free' here; first 'free' was at (2) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_1()': events 1-3 + | + | NN | void *ptr = malloc (1024); + | | ~~~~~~~^~~~~~ + | | | + | | (1) allocated here + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (2) first 'free' here + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (3) second 'free' here; first 'free' was at (2) + | + { dg-end-multiline-output "" { target c++ } } */ + +void test_2 (int x, int y) +{ + void *ptr = malloc (1024); + if (x) + free (ptr); + if (y) + free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */ +} /* { dg-warning "leak of 'ptr'" } */ + +/* "double-'free' of 'ptr'". */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ^~~~~~~~~~ + 'test_2': events 1-7 + | + | NN | void *ptr = malloc (1024); + | | ^~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | if (x) + | | ~ + | | | + | | (2) following 'true' branch (when 'x != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (3) ...to here + | | (4) first 'free' here + | NN | if (y) + | | ~ + | | | + | | (5) following 'true' branch (when 'y != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) ...to here + | | (7) second 'free' here; first 'free' was at (4) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | free (ptr); + | ~~~~~^~~~~ + 'void test_2(int, int)': events 1-7 + | + | NN | void *ptr = malloc (1024); + | | ~~~~~~~^~~~~~ + | | | + | | (1) allocated here + | NN | if (x) + | | ~~ + | | | + | | (2) following 'true' branch (when 'x != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (3) ...to here + | | (4) first 'free' here + | NN | if (y) + | | ~~ + | | | + | | (5) following 'true' branch (when 'y != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) ...to here + | | (7) second 'free' here; first 'free' was at (4) + | + { dg-end-multiline-output "" { target c++ } } */ + +/* "leak of 'ptr'. */ +/* { dg-begin-multiline-output "" } + NN | } + | ^ + 'test_2': events 1-6 + | + | NN | void *ptr = malloc (1024); + | | ^~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | if (x) + | | ~ + | | | + | | (2) following 'false' branch (when 'x == 0')... + | NN | free (ptr); + | NN | if (y) + | | ~ + | | | + | | (3) ...to here + | | (4) following 'false' branch (when 'y == 0')... + | NN | free (ptr); + | NN | } + | | ~ + | | | + | | (5) ...to here + | | (6) 'ptr' leaks here; was allocated at (1) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | } + | ^ + 'void test_2(int, int)': events 1-6 + | + | NN | void *ptr = malloc (1024); + | | ~~~~~~~^~~~~~ + | | | + | | (1) allocated here + | NN | if (x) + | | ~~ + | | | + | | (2) following 'false' branch (when 'x == 0')... + | NN | free (ptr); + | NN | if (y) + | | ~~ + | | | + | | (3) ...to here + | | (4) following 'false' branch (when 'y == 0')... + | NN | free (ptr); + | NN | } + | | ~ + | | | + | | (5) ...to here + | | (6) 'ptr' leaks here; was allocated at (1) + | + { dg-end-multiline-output "" { target c++ } } */ + +int test_3 (int x, int y) +{ + int *ptr = (int *)malloc (sizeof (int)); + *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */ + if (x) + free (ptr); + + *ptr = 19; /* { dg-warning "use after 'free' of 'ptr'" } */ + // TODO: two warnings here: one is from sm-malloc, the other from region model + + if (y) + free (ptr); /* No double-'free' warning: we've already attempted + to dereference it above. */ + return *ptr; /* { dg-warning "use after 'free' of 'ptr'" "use-after-free" } */ + /* { dg-warning "leak of 'ptr'" "leak" { target *-*-* } .-1 } */ +} + +/* "dereference of possibly-NULL 'ptr'". */ +/* { dg-begin-multiline-output "" } + NN | *ptr = 42; + | ~~~~~^~~~ + 'test_3': events 1-2 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ^~~~~~~~~~~~~~~~~~~~~ + | | | + | | (1) this call could return NULL + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) 'ptr' could be NULL: unchecked value from (1) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | *ptr = 42; + | ~~~~~^~~~ + 'int test_3(int, int)': events 1-2 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ~~~~~~~^~~~~~~~~~~~~~ + | | | + | | (1) this call could return NULL + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) 'ptr' could be NULL: unchecked value from (1) + | + { dg-end-multiline-output "" { target c++ } } */ + +/* "use after 'free' of 'ptr'". */ +/* { dg-begin-multiline-output "" } + NN | *ptr = 19; + | ~~~~~^~~~ + 'test_3': events 1-6 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ^~~~~~~~~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) assuming 'ptr' is non-NULL + | NN | if (x) + | | ~ + | | | + | | (3) following 'true' branch (when 'x != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (4) ...to here + | | (5) freed here + | NN | + | NN | *ptr = 19; + | | ~~~~~~~~~ + | | | + | | (6) use after 'free' of 'ptr'; freed at (5) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | *ptr = 19; + | ~~~~~^~~~ + 'int test_3(int, int)': events 1-6 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ~~~~~~~^~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) assuming 'ptr' is non-NULL + | NN | if (x) + | | ~~ + | | | + | | (3) following 'true' branch (when 'x != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (4) ...to here + | | (5) freed here + | NN | + | NN | *ptr = 19; + | | ~~~~~~~~~ + | | | + | | (6) use after 'free' of 'ptr'; freed at (5) + | + { dg-end-multiline-output "" { target c++ } } */ + +/* "use after 'free' of 'ptr'". */ +/* { dg-begin-multiline-output "" } + NN | return *ptr; + | ^~~~ + 'test_3': events 1-8 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ^~~~~~~~~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) assuming 'ptr' is non-NULL + | NN | if (x) + | | ~ + | | | + | | (3) following 'false' branch (when 'x == 0')... + |...... + | NN | *ptr = 19; + | | ~~~~~~~~~ + | | | + | | (4) ...to here + |...... + | NN | if (y) + | | ~ + | | | + | | (5) following 'true' branch (when 'y != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) ...to here + | | (7) freed here + | NN | + | NN | return *ptr; + | | ~~~~ + | | | + | | (8) use after 'free' of 'ptr'; freed at (7) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | return *ptr; + | ^~~ + 'int test_3(int, int)': events 1-8 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ~~~~~~~^~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) assuming 'ptr' is non-NULL + | NN | if (x) + | | ~~ + | | | + | | (3) following 'false' branch (when 'x == 0')... + |...... + | NN | *ptr = 19; + | | ~~~~~~~~~ + | | | + | | (4) ...to here + |...... + | NN | if (y) + | | ~~ + | | | + | | (5) following 'true' branch (when 'y != 0')... + | NN | free (ptr); + | | ~~~~~~~~~~ + | | | + | | (6) ...to here + | | (7) freed here + | NN | + | NN | return *ptr; + | | ~~~ + | | | + | | (8) use after 'free' of 'ptr'; freed at (7) + | + { dg-end-multiline-output "" { target c++ } } */ + +/* "leak of 'ptr'". */ +/* { dg-begin-multiline-output "" } + NN | return *ptr; + | ^~~~ + 'test_3': events 1-7 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ^~~~~~~~~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) assuming 'ptr' is non-NULL + | NN | if (x) + | | ~ + | | | + | | (3) following 'false' branch (when 'x == 0')... + |...... + | NN | *ptr = 19; + | | ~~~~~~~~~ + | | | + | | (4) ...to here + |...... + | NN | if (y) + | | ~ + | | | + | | (5) following 'false' branch (when 'y == 0')... + |...... + | NN | return *ptr; + | | ~~~~ + | | | + | | (6) ...to here + | | (7) 'ptr' leaks here; was allocated at (1) + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | return *ptr; + | ^~~ + 'int test_3(int, int)': events 1-7 + | + | NN | int *ptr = (int *)malloc (sizeof (int)); + | | ~~~~~~~^~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | NN | *ptr = 42; + | | ~~~~~~~~~ + | | | + | | (2) assuming 'ptr' is non-NULL + | NN | if (x) + | | ~~ + | | | + | | (3) following 'false' branch (when 'x == 0')... + |...... + | NN | *ptr = 19; + | | ~~~~~~~~~ + | | | + | | (4) ...to here + |...... + | NN | if (y) + | | ~~ + | | | + | | (5) following 'false' branch (when 'y == 0')... + |...... + | NN | return *ptr; + | | ~~~ + | | | + | | (6) ...to here + | | (7) 'ptr' leaks here; was allocated at (1) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c index 1e4613c..1151d62 100644 --- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c +++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c @@ -1,6 +1,5 @@ /* Reduced from SoftEtherVPN's src/Cedar/WebUI.c. */ - -#define NULL ((void *)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" typedef int (COMPARE)(void *p1, void *p2); typedef unsigned int UINT; typedef unsigned long int UINT64; @@ -28,7 +27,11 @@ struct LIST #define LIST_DATA(o, i) (((o) != NULL) ? ((o)->p[(i)]) : NULL) #define LIST_NUM(o) (((o) != NULL) ? (o)->num_item : 0) - +#ifdef __cplusplus +#ifndef _Bool +typedef bool _Bool; +#endif +#endif struct STRMAP_ENTRY { @@ -65,10 +68,10 @@ void WuExpireSessionKey(WEBUI *wu) for(i=0; i<LIST_NUM(Expired); i++) { - STRMAP_ENTRY *entry = LIST_DATA(Expired, i); + STRMAP_ENTRY *entry = (STRMAP_ENTRY*)LIST_DATA(Expired, i); Delete(wu->Contexts, entry); Free(entry->Name); - WuFreeContext(entry->Value); + WuFreeContext((WU_CONTEXT*)entry->Value); Free(entry); } ReleaseList(Expired); diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-1.c index 93b379c..868b8ee 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-1.c @@ -54,7 +54,7 @@ void test3 (void) void test4 (void) { - int *arr = malloc (4 * sizeof (int)); + int *arr = (int *)malloc (4 * sizeof (int)); if (!arr) return; @@ -66,7 +66,7 @@ void test4 (void) void test5 (void) { - int *arr = malloc (4 * sizeof (int)); + int *arr = (int *)malloc (4 * sizeof (int)); if (!arr) return; @@ -99,7 +99,7 @@ void test6 (void) extern int is_valid (void); -int returnChunkSize (void *ptr) +int returnChunkSize (int *ptr) { /* If chunk info is valid, return the size of usable memory, else, return -1 to indicate an error. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-2.c index 336f624..e696146 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-2.c @@ -54,7 +54,7 @@ void test3 (void) void test4 (void) { int n = 4; - int *arr = malloc (n * sizeof (int)); + int *arr = (int *)malloc (n * sizeof (int)); if (!arr) return; memset (arr, 0, n * sizeof(int)); @@ -69,7 +69,7 @@ void test4 (void) void test5 (void) { int n = 4; - int *arr = malloc (n * sizeof (int)); + int *arr = (int *)malloc (n * sizeof (int)); if (!arr) return; memset (arr, 0, n * sizeof(int)); diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-5.c index 568f9ca..4d15b16 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-5.c @@ -9,7 +9,7 @@ void test1 (size_t size) { - char *buf = __builtin_malloc (size); + char *buf = (char *)__builtin_malloc (size); if (!buf) return; buf[size] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ @@ -18,7 +18,7 @@ void test1 (size_t size) void test2 (size_t size) { - char *buf = __builtin_malloc (size); + char *buf = (char *)__builtin_malloc (size); if (!buf) return; buf[size + 1] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ @@ -27,7 +27,7 @@ void test2 (size_t size) void test3 (size_t size, size_t op) { - char *buf = __builtin_malloc (size); + char *buf = (char *)__builtin_malloc (size); if (!buf) return; buf[size + op] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ @@ -36,26 +36,26 @@ void test3 (size_t size, size_t op) void test4 (size_t size, unsigned short s) { - char *buf = __builtin_alloca (size); + char *buf = (char *)__builtin_alloca (size); buf[size + s] = '\0'; /* { dg-warning "stack-based buffer overflow" } */ } void test5 (size_t size) { - int32_t *buf = __builtin_alloca (4 * size); + int32_t *buf = (int32_t *)__builtin_alloca (4 * size); buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */ } void test6 (size_t size) { - int32_t *buf = __builtin_alloca (4 * size); + int32_t *buf = (int32_t *)__builtin_alloca (4 * size); memset (buf, 0, 4 * size); int32_t last = *(buf + 4 * size); /* { dg-warning "stack-based buffer over-read" } */ } void test7 (size_t size) { - int32_t *buf = __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + int32_t *buf = (int32_t *)__builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */ } @@ -91,7 +91,7 @@ void test10 (size_t size) void test11 (size_t size) { - int32_t *buf = __builtin_alloca (4 * size + 5); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + int32_t *buf = (int32_t *)__builtin_alloca (4 * size + 5); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ buf[size] = 42; } @@ -129,7 +129,7 @@ char *test98 (const char *x, const char *y) size_t len_x = __builtin_strlen (x); size_t len_y = __builtin_strlen (y); size_t sz = len_x + len_y + 1; - char *result = __builtin_malloc (sz); + char *result = (char *)__builtin_malloc (sz); if (!result) return NULL; __builtin_memcpy (result, x, len_x); @@ -144,7 +144,7 @@ char *test99 (const char *x, const char *y) size_t len_y = __builtin_strlen (y); /* BUG (root cause): forgot to add 1 for terminator. */ size_t sz = len_x + len_y; - char *result = __builtin_malloc (sz); + char *result = (char *)__builtin_malloc (sz); if (!result) return NULL; __builtin_memcpy (result, x, len_x); diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-11.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-11.c index f8eb158..d68ac8f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-11.c +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-11.c @@ -7,7 +7,7 @@ void test6 (size_t size) { - int32_t *buf = __builtin_alloca (4 * size); + int32_t *buf = (int32_t *) __builtin_alloca (4 * size); memset (buf, 0, 4 * size); int32_t last = *(buf + 4 * size); /* { dg-warning "stack-based buffer over-read" } */ } @@ -38,7 +38,7 @@ void test6 (size_t size) void test7 (size_t size) { - int32_t *buf = __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + int32_t *buf = (int32_t *) __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */ } @@ -71,7 +71,7 @@ char *test99 (const char *x, const char *y) size_t len_y = __builtin_strlen (y); /* BUG (root cause): forgot to add 1 for terminator. */ size_t sz = len_x + len_y; - char *result = __builtin_malloc (sz); + char *result = (char *) __builtin_malloc (sz); if (!result) return NULL; __builtin_memcpy (result, x, len_x); diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-3.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-3.c index 064f3fa..43df956 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-3.c +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-3.c @@ -16,7 +16,8 @@ struct str * make_str_badly (const char *src) { size_t len = strlen(src); - struct str *str = malloc(sizeof(str) + len); /* { dg-message "\\(1\\) capacity: 'len \\+ 8' bytes" } */ + struct str *str = (struct str *) malloc(sizeof(str) + len); /* { dg-message "\\(1\\) capacity: 'len \\+ 8' bytes" "" { target c } } */ + /* { dg-message "\\(1\\) capacity: '\\(len \\+ 8\\)' bytes" "" { target c++ } .-1 } */ if (!str) return NULL; str->len = len; diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-8.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-8.c index 24d8735..81cd4ff 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-8.c +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-diagram-8.c @@ -7,7 +7,8 @@ void test2 (size_t size) { - int32_t *buf = __builtin_malloc (size * sizeof(int32_t)); /* { dg-message "\\(1\\) capacity: 'size \\* 4' bytes" } */ + int32_t *buf = (int32_t *) __builtin_malloc (size * sizeof(int32_t)); /* { dg-message "\\(1\\) capacity: 'size \\* 4' bytes" "" { target c } } */ + /* { dg-message "\\(1\\) capacity: '\\(size \\* 4\\)' bytes" "" { target c++ } .-1 } */ if (!buf) return; buf[size + 1] = 42; /* { dg-warning "heap-based buffer overflow" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/phi-1.c b/gcc/testsuite/c-c++-common/analyzer/phi-1.c index 0926003..7818935 100644 --- a/gcc/testsuite/gcc.dg/analyzer/phi-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/phi-1.c @@ -1,7 +1,7 @@ /* { dg-do "compile" } */ typedef __SIZE_TYPE__ size_t; -#define NULL ((void *) 0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern const char *foo (void); extern size_t bar (void); diff --git a/gcc/testsuite/gcc.dg/analyzer/pr100615.c b/gcc/testsuite/c-c++-common/analyzer/pr100615.c index 7a06f98..f4b29f4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr100615.c +++ b/gcc/testsuite/c-c++-common/analyzer/pr100615.c @@ -3,7 +3,7 @@ which is MIT-licensed. */ typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103526.c b/gcc/testsuite/c-c++-common/analyzer/pr103526.c index 39d60fd..0388fc1 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr103526.c +++ b/gcc/testsuite/c-c++-common/analyzer/pr103526.c @@ -17,9 +17,9 @@ game_new(void) tmp.word = teststr; wordlen = strlen(tmp.word); - if ((tmp.word_state = malloc(wordlen+1)) == NULL) + if ((tmp.word_state = (char *) malloc(wordlen+1)) == NULL) goto err; - if ((rval = malloc(sizeof(*rval))) == NULL) + if ((rval = (struct game_state *) malloc(sizeof(*rval))) == NULL) goto err; memcpy(rval, &tmp, sizeof(*rval)); diff --git a/gcc/testsuite/c-c++-common/analyzer/pr109577-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/pr109577-noexcept.c new file mode 100644 index 0000000..4ff7a5b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr109577-noexcept.c @@ -0,0 +1,2 @@ +/* { dg-additional-options "-fno-exceptions" } */ +#include "../../gcc.dg/analyzer/pr109577.c" diff --git a/gcc/testsuite/c-c++-common/analyzer/pr110830.c b/gcc/testsuite/c-c++-common/analyzer/pr110830.c new file mode 100644 index 0000000..f5a39b7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr110830.c @@ -0,0 +1,111 @@ +typedef __SIZE_TYPE__ size_t; + +void free(void *); +void *malloc(__SIZE_TYPE__); + +extern int ext(); + +void test_supersedes () +{ + int *p = (int *)malloc(sizeof(int)); + free(p); + int x = *p + 4; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-bogus "use of uninitialized value '\\*p" "" { target *-*-* } .-1 } */ +} + +int *called_by_test0() +{ + int *p = 0; + if (ext()) + { + p = (int *)malloc(sizeof(int)); + free(p); + return p; + } + else + return (int *)malloc(sizeof(int)); +} + +void test0() +{ + int *y = called_by_test0(); + int x = 0; + if (y != 0) + x = *y; /* { dg-warning "use after 'free' of 'y'" } */ + /* { dg-warning "use of uninitialized value '\\*y'" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + free(y); /* { dg-warning "double-'free'" } */ +} + +void test1() +{ + int *p = 0; + if (ext()) + { + p = (int *)malloc(sizeof(int)); + free(p); + } + else + p = (int *)malloc(sizeof(int)); + + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p'" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + free(p); /* { dg-warning "double-'free'" } */ +} + +void test2() +{ + int *p = 0; + p = (int *)malloc(sizeof(int)); + if (ext()) + free(p); + + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p'" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + free(p); /* { dg-warning "double-'free'" } */ +} + +void test3() +{ + int *p = 0; + p = (int *)malloc(sizeof(int)); + int i = 100; + while (i--) + { + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p'" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + p = (int *)malloc(sizeof(int)); + free(p); + } + + free(p); /* { dg-warning "double-'free'" } */ +} + + +void test4() +{ + int *p = 0; + if (ext()) + { + p = (int *) malloc(sizeof(int)); + if (ext () > 5) + { + mal: + free (p); + } + } + else { + goto mal; + } + + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p'" "" { target *-*-* } .-1 } */ + free(p); /* { dg-warning "double-'free'" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr93355-localealias-feasibility-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/pr93355-localealias-feasibility-noexcept.c new file mode 100644 index 0000000..6ab14fb --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr93355-localealias-feasibility-noexcept.c @@ -0,0 +1,85 @@ +/* Simplified version of test to ensure we issue a FILE * leak diagnostic, + reproducing a feasibility issue. + Adapted from intl/localealias.c, with all #includes removed. */ + +/* { dg-do "compile" } */ +/* { dg-additional-options "-fno-exceptions" } */ + +/* Handle aliases for locale names. + Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ + + +#include "../../gcc.dg/analyzer/analyzer-decls.h" +/* Minimal version of system headers. */ +typedef __SIZE_TYPE__ size_t; + +typedef struct _IO_FILE FILE; +extern FILE *fopen (const char *__restrict __filename, + const char *__restrict __modes); +extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +extern int fclose (FILE *__stream); + +extern int isspace (int) __attribute__((__nothrow__, __leaf__)); + +/* Cleaned-up body of localealias.c follows. */ + +size_t +read_alias_file (const char *fname, int fname_len) +{ + FILE *fp; + size_t added; + char buf[400]; + char *alias; + char *value; + char *cp; + + fp = fopen (fname, "r"); /* { dg-message "opened here" } */ + if (fp == NULL) + return 0; + + if (fread (buf, sizeof buf, 1, fp) != 1) + { + fclose (fp); + return 0; + } + + cp = buf; + + /* Ignore leading white space. */ + while (isspace ((unsigned char)cp[0])) + ++cp; + + if (cp[0] != '\0' && cp[0] != '#') + { + alias = cp++; + while (cp[0] != '\0' && !isspace ((unsigned char)cp[0])) + ++cp; + if (cp[0] != '\0') + *cp++ = '\0'; + + while (isspace ((unsigned char)cp[0])) + ++cp; + + if (cp[0] != '\0') + return 42; /* { dg-warning "leak of FILE 'fp'" } */ + } + + fclose(fp); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94362-1.c b/gcc/testsuite/c-c++-common/analyzer/pr94362-1.c index 1302ced..a184636 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr94362-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/pr94362-1.c @@ -17,7 +17,7 @@ sk_EVP_PKEY_ASN1_METHOD_value(const struct stack_st_EVP_PKEY_ASN1_METHOD *sk, int idx); extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {&hmac_asn1_meth}; -static struct stack_st_EVP_PKEY_ASN1_METHOD *app_methods = ((void *)0); +static struct stack_st_EVP_PKEY_ASN1_METHOD *app_methods = (struct stack_st_EVP_PKEY_ASN1_METHOD *) ((void *)0); int EVP_PKEY_asn1_get_count(void) { int num = (sizeof(standard_methods) / sizeof((standard_methods)[0])); @@ -29,7 +29,7 @@ int EVP_PKEY_asn1_get_count(void) { const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) { int num = (sizeof(standard_methods) / sizeof((standard_methods)[0])); if (idx < 0) - return ((void *)0); + return (const EVP_PKEY_ASN1_METHOD *) ((void *)0); if (idx < num) return standard_methods[idx]; idx -= num; @@ -39,7 +39,7 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) { const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len) { int i; - const EVP_PKEY_ASN1_METHOD *ameth = ((void *)0); + const EVP_PKEY_ASN1_METHOD *ameth = (const EVP_PKEY_ASN1_METHOD *) ((void *)0); if (pe) { ENGINE *e; @@ -48,7 +48,7 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, *pe = e; return ameth; } - *pe = ((void *)0); + *pe = (ENGINE *) ((void *)0); } for (i = EVP_PKEY_asn1_get_count(); i-- > 0;) { ameth = EVP_PKEY_asn1_get0(i); @@ -56,5 +56,5 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, continue; return ameth; } - return ((void *)0); + return (const EVP_PKEY_ASN1_METHOD *) ((void *)0); } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97074.c b/gcc/testsuite/c-c++-common/analyzer/pr97074.c index ccb3b61..2dee909 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr97074.c +++ b/gcc/testsuite/c-c++-common/analyzer/pr97074.c @@ -1,5 +1,4 @@ -#include "analyzer-decls.h" -#define NULL ((void *)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" void *x, *y; diff --git a/gcc/testsuite/c-c++-common/analyzer/pr99193-1-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/pr99193-1-noexcept.c new file mode 100644 index 0000000..ac0d3dd6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr99193-1-noexcept.c @@ -0,0 +1,68 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ +/* { dg-additional-options "-fno-exceptions" } */ + +/* Verify absence of false positive from -Wanalyzer-mismatching-deallocation + on realloc(3). + Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/command.c#L115 + which is GPLv2 or later. */ + +typedef __SIZE_TYPE__ size_t; +typedef __builtin_va_list va_list; + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void perror (const char *__s); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); + +extern void guestfs_int_cleanup_free (void *ptr); +extern int commandrvf (char **stdoutput, char **stderror, unsigned flags, + char const* const *argv); +#define CLEANUP_FREE __attribute__((cleanup(guestfs_int_cleanup_free))) + +int +commandrf (char **stdoutput, char **stderror, unsigned flags, + const char *name, ...) +{ + va_list args; + CLEANUP_FREE const char **argv = NULL; + char *s; + int i, r; + + /* Collect the command line arguments into an array. */ + i = 2; + argv = (const char **) malloc (sizeof (char *) * i); + + if (argv == NULL) { + perror ("malloc"); + return -1; + } + argv[0] = (char *) name; + argv[1] = NULL; + + __builtin_va_start (args, name); + + while ((s = __builtin_va_arg (args, char *)) != NULL) { + const char **p = (const char **) realloc (argv, sizeof (char *) * (++i)); /* { dg-bogus "'free'" } */ + if (p == NULL) { + perror ("realloc"); + __builtin_va_end (args); + return -1; + } + argv = p; + argv[i-2] = s; + argv[i-1] = NULL; + } + + __builtin_va_end (args); + + r = commandrvf (stdoutput, stderror, flags, argv); + + return r; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c b/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c index 12326ef..f033a26 100644 --- a/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c @@ -8,7 +8,7 @@ typedef __SIZE_TYPE__ size_t; typedef __builtin_va_list va_list; -#define NULL ((void *)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern void free (void *); extern void *realloc (void *__ptr, size_t __size) diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-1.c b/gcc/testsuite/c-c++-common/analyzer/realloc-1.c index 75e0b10e..04925cf 100644 --- a/gcc/testsuite/c-c++-common/analyzer/realloc-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-1.c @@ -2,7 +2,7 @@ typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern void *malloc (size_t __size) __attribute__ ((__nothrow__ , __leaf__)) diff --git a/gcc/testsuite/gcc.dg/analyzer/scope-1.c b/gcc/testsuite/c-c++-common/analyzer/scope-1.c index f8acffa..09e62d4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/scope-1.c +++ b/gcc/testsuite/c-c++-common/analyzer/scope-1.c @@ -3,7 +3,7 @@ int test_1 (void) { { - int *q = malloc (1024); + int *q = (int *) malloc (1024); } return 42; /* { dg-warning "leak of 'q'" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-2.c b/gcc/testsuite/c-c++-common/analyzer/setjmp-2.c index f5d9c53..731a172 100644 --- a/gcc/testsuite/gcc.dg/analyzer/setjmp-2.c +++ b/gcc/testsuite/c-c++-common/analyzer/setjmp-2.c @@ -2,9 +2,9 @@ /* { dg-enable-nn-line-numbers "" } */ /* { dg-require-effective-target indirect_jumps } */ -#include "test-setjmp.h" +#include "../../gcc.dg/analyzer/test-setjmp.h" #include <stddef.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern void foo (int); @@ -81,7 +81,54 @@ void test_2 (void) | | | | | (8) here | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | __analyzer_dump_path (); + | ~~~~~~~~~~~~~~~~~~~~~^~ + 'void test_2()': event 1 + | + | NN | i = SETJMP(env); + | | ^~~~~~ + | | | + | | (1) 'setjmp' called here + | + 'void test_2()': events 2-4 + | + | NN | if (i != 0) + | | ^~ + | | | + | | (2) following 'false' branch (when 'i == 0')... + |...... + | NN | longjmp (env, 1); + | | ~~~~~~~~~~~~~~~~ + | | | + | | (3) ...to here + | | (4) rewinding within 'test_2' from 'longjmp'... + | + 'void test_2()': event 5 + | + | NN | i = SETJMP(env); + | | ^~~~~~ + | | | + | | (5) ...to 'setjmp' (saved at (1)) + | + 'void test_2()': events 6-8 + | + | NN | if (i != 0) + | | ^~ + | | | + | | (6) following 'true' branch (when 'i != 0')... + | NN | { + | NN | foo (2); + | | ~~~~~~~ + | | | + | | (7) ...to here + | NN | __analyzer_dump_path (); + | | ~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (8) here + | + { dg-end-multiline-output "" { target c++ } } */ void test_3 (void) { diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c b/gcc/testsuite/c-c++-common/analyzer/setjmp-5.c index 4787fa3..3133a47 100644 --- a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c +++ b/gcc/testsuite/c-c++-common/analyzer/setjmp-5.c @@ -2,9 +2,9 @@ /* { dg-enable-nn-line-numbers "" } */ /* { dg-require-effective-target indirect_jumps } */ -#include "test-setjmp.h" +#include "../../gcc.dg/analyzer/test-setjmp.h" #include <stddef.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" static jmp_buf env; @@ -72,4 +72,55 @@ void outer (void) | | | | | (7) 'longjmp' called after enclosing function of 'setjmp' returned at (5) | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | longjmp (env, 42); + | ~~~~~~~~^~~~~~~~~ + 'void outer()': events 1-2 + | + | NN | void outer (void) + | | ^~~~~ + | | | + | | (1) entry to 'outer' + |...... + | NN | inner (); + | | ~~~~~~~~ + | | | + | | (2) calling 'inner' from 'outer' + | + +--> 'void inner()': event 3 + | + | NN | static void inner (void) + | | ^~~~~ + | | | + | | (3) entry to 'inner' + | + 'void inner()': event 4 + | + | NN | SETJMP (env); + | | ^~~~~~ + | | | + | | (4) 'setjmp' called here + | + 'void inner()': event 5 + | + | NN | } + | | ^ + | | | + | | (5) stack frame is popped here, invalidating saved environment + | + <------+ + | + 'void outer()': events 6-7 + | + | NN | inner (); + | | ~~~~~~^~ + | | | + | | (6) returning to 'outer' from 'inner' + | NN | + | NN | longjmp (env, 42); + | | ~~~~~~~~~~~~~~~~~ + | | | + | | (7) 'longjmp' called after enclosing function of 'setjmp' returned at (5) + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-9.c b/gcc/testsuite/c-c++-common/analyzer/setjmp-9.c index c2b00e3..f7e940e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/setjmp-9.c +++ b/gcc/testsuite/c-c++-common/analyzer/setjmp-9.c @@ -2,9 +2,9 @@ /* { dg-enable-nn-line-numbers "" } */ /* { dg-require-effective-target indirect_jumps } */ -#include "test-setjmp.h" +#include "../../gcc.dg/analyzer/test-setjmp.h" #include <stddef.h> -#include "analyzer-decls.h" +#include "../../gcc.dg/analyzer/analyzer-decls.h" extern int foo (int) __attribute__ ((__pure__)); @@ -41,6 +41,71 @@ void outer (void) /* { dg-begin-multiline-output "" } NN | __analyzer_dump_path (); + | ~~~~~~~~~~~~~~~~~~~~~^~ + 'void outer()': event 1 + | + | NN | void outer (void) + | | ^~~~~ + | | | + | | (1) entry to 'outer' + | + 'void outer()': event 2 + | + | NN | i = SETJMP(env); + | | ^~~~~~ + | | | + | | (2) 'setjmp' called here + | + 'void outer()': events 3-5 + | + | NN | if (i != 0) + | | ^~ + | | | + | | (3) following 'false' branch (when 'i == 0')... + |...... + | NN | inner (); + | | ~~~~~~~~ + | | | + | | (4) ...to here + | | (5) calling 'inner' from 'outer' + | + +--> 'void inner()': events 6-7 + | + | NN | static void inner (void) + | | ^~~~~ + | | | + | | (6) entry to 'inner' + |...... + | NN | longjmp (env, unknown_val); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (7) rewinding from 'longjmp' in 'inner'... + | + <------+ + | + 'void outer()': event 8 + | + | NN | i = SETJMP(env); + | | ^~~~~~ + | | | + | | (8) ...to 'setjmp' in 'outer' (saved at (2)) + | + 'void outer()': events 9-11 + | + | NN | if (i != 0) + | | ^~ + | | | + | | (9) following 'true' branch (when 'i != 0')... + |...... + | NN | __analyzer_dump_path (); + | | ~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (10) ...to here + | | (11) here + | + { dg-end-multiline-output "" { target c++ } } */ +/* { dg-begin-multiline-output "" } + NN | __analyzer_dump_path (); | ^~~~~~~~~~~~~~~~~~~~~~~ 'outer': event 1 | @@ -109,4 +174,4 @@ void outer (void) | | | | | (11) here | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-4a.c b/gcc/testsuite/c-c++-common/analyzer/signal-4a.c index 4ee6f0e..b5c6012 100644 --- a/gcc/testsuite/gcc.dg/analyzer/signal-4a.c +++ b/gcc/testsuite/c-c++-common/analyzer/signal-4a.c @@ -12,7 +12,8 @@ extern void body_of_program(void); void custom_logger(const char *msg) { - fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" } */ + fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" "" { target c } } */ + /* { dg-warning "call to 'int fprintf\\(FILE\\*, const char\\*, ...\\)' from within signal handler" "" { target c++ } .-1 } */ } static void int_handler(int signum) @@ -73,4 +74,49 @@ void test (void) | | | | | (7) call to 'fprintf' from within signal handler | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | fprintf(stderr, "LOG: %s", msg); + | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ + 'void test()': events 1-2 + | + | NN | void test (void) + | | ^~~~ + | | | + | | (1) entry to 'test' + |...... + | NN | signal(SIGINT, int_handler); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (2) registering 'void int_handler(int)' as signal handler + | + event 3 + | + |cc1plus: + | (3): later on, when the signal is delivered to the process + | + +--> 'void int_handler(int)': events 4-5 + | + | NN | static void int_handler(int signum) + | | ^~~~~~~~~~~ + | | | + | | (4) entry to 'int_handler' + | NN | { + | NN | custom_logger("got signal"); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (5) calling 'custom_logger' from 'int_handler' + | + +--> 'void custom_logger(const char*)': events 6-7 + | + | NN | void custom_logger(const char *msg) + | | ^~~~~~~~~~~~~ + | | | + | | (6) entry to 'custom_logger' + | NN | { + | NN | fprintf(stderr, "LOG: %s", msg); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (7) call to 'int fprintf(FILE*, const char*, ...)' from within signal handler + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-4b.c b/gcc/testsuite/c-c++-common/analyzer/signal-4b.c index 5a2ccb1..d2b5db7 100644 --- a/gcc/testsuite/gcc.dg/analyzer/signal-4b.c +++ b/gcc/testsuite/c-c++-common/analyzer/signal-4b.c @@ -12,7 +12,8 @@ extern void body_of_program(void); void custom_logger(const char *msg) { - fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" } */ + fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" "" { target c } } */ + /* { dg-warning "call to 'int fprintf\\(FILE\\*, const char\\*, ...\\)' from within signal handler" "" { target c++ } .-1 } */ } static void int_handler(int signum) @@ -88,4 +89,61 @@ void test (void) | | | | | (9) call to 'fprintf' from within signal handler | - { dg-end-multiline-output "" } */ + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + NN | fprintf(stderr, "LOG: %s", msg); + | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ + 'void test()': events 1-2 + | + | NN | void test (void) + | | ^~~~ + | | | + | | (1) entry to 'test' + | NN | { + | NN | __analyzer_register_handler (); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (2) calling '__analyzer_register_handler' from 'test' + | + +--> 'void __analyzer_register_handler()': events 3-4 + | + | NN | static void __analyzer_register_handler () + | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (3) entry to '__analyzer_register_handler' + | NN | { + | NN | signal(SIGINT, int_handler); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (4) registering 'void int_handler(int)' as signal handler + | + event 5 + | + |cc1plus: + | (5): later on, when the signal is delivered to the process + | + +--> 'void int_handler(int)': events 6-7 + | + | NN | static void int_handler(int signum) + | | ^~~~~~~~~~~ + | | | + | | (6) entry to 'int_handler' + | NN | { + | NN | custom_logger("got signal"); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (7) calling 'custom_logger' from 'int_handler' + | + +--> 'void custom_logger(const char*)': events 8-9 + | + | NN | void custom_logger(const char *msg) + | | ^~~~~~~~~~~~~ + | | | + | | (8) entry to 'custom_logger' + | NN | { + | NN | fprintf(stderr, "LOG: %s", msg); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (9) call to 'int fprintf(FILE*, const char*, ...)' from within signal handler + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-nondep4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-nondep4.C new file mode 100644 index 0000000..9a8db55 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-nondep4.C @@ -0,0 +1,16 @@ +// PR c++/99599 +// { dg-do compile { target c++20 } } + +struct foo_tag { }; +struct bar_tag { }; + +template<class T> +concept fooable = requires(T it) { invoke_tag(foo_tag{}, it); }; + +template<class T> void invoke_tag(foo_tag, T); +template<class T> void invoke_tag(bar_tag, T) requires fooable<T>; + +int main() { + invoke_tag(foo_tag{}, 0); + invoke_tag(bar_tag{}, 0); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat4.C index 18d126e..08f206d 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat4.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat4.C @@ -1,3 +1,4 @@ +// Verify we diagnose constraint recursion. // PR c++/96840 // { dg-do compile { target c++20 } } @@ -6,6 +7,7 @@ template <class T, class U> concept C = requires(T t, U u) { t * u; }; // { dg-error "depends on itself" "" { target *-*-* } .-2 } template <class Rep> struct Int { + Int(); // make the class non-aggregate in light of PR99599 fix template <class T> requires C<T, Rep> friend void operator*(T, Int) { } template <class T> requires C<T, Rep> friend void operator*(Int, T) { } }; diff --git a/gcc/testsuite/g++.dg/gomp/pr111274.C b/gcc/testsuite/g++.dg/gomp/pr111274.C new file mode 100644 index 0000000..6d3414f --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr111274.C @@ -0,0 +1,15 @@ +// { dg-do "compile" } + +// This example used to ICE in fixup_blocks_walker due to a BIND_EXPR with +// null BIND_EXPR_BLOCK. + +struct _Vector_base { + ~_Vector_base(); +}; +int ColumnSmallestLastOrdering_OMP_i_MaxNumThreads, + ColumnSmallestLastOrdering_OMP_i_MaxDegree; +void ColumnSmallestLastOrdering_OMP() { +#pragma omp for + for (int i = 0; i < ColumnSmallestLastOrdering_OMP_i_MaxNumThreads; i++) + new _Vector_base[ColumnSmallestLastOrdering_OMP_i_MaxDegree]; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111331-1.c b/gcc/testsuite/gcc.c-torture/execute/pr111331-1.c new file mode 100644 index 0000000..4c7f4fd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr111331-1.c @@ -0,0 +1,17 @@ +int a; +int b; +int c(int d, int e, int f) { + if (d < e) + return e; + if (d > f) + return f; + return d; +} +int main() { + int g = -1; + a = c(b + 30, 29, g + 29); + volatile t = a; + if (t != 28) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111331-2.c b/gcc/testsuite/gcc.c-torture/execute/pr111331-2.c new file mode 100644 index 0000000..5c677f2 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr111331-2.c @@ -0,0 +1,19 @@ + +int a; +int b; + +int main() { + int d = b+30; + { + int t; + if (d < 29) + t = 29; + else + t = (d > 28) ? 28 : d; + a = t; + } + volatile int t = a; + if (a != 28) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111331-3.c b/gcc/testsuite/gcc.c-torture/execute/pr111331-3.c new file mode 100644 index 0000000..213d9bd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr111331-3.c @@ -0,0 +1,15 @@ +int a; +int b; + +int main() { + int d = b+30; + { + int t; + t = d < 29 ? 29 : ((d > 28) ? 28 : d); + a = t; + } + volatile int t = a; + if (a != 28) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c deleted file mode 100644 index 0f07818..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c +++ /dev/null @@ -1,70 +0,0 @@ -#include <stdlib.h> - -struct ptr_wrapper -{ - int *ptr; -}; - -struct ptr_wrapper -test_1 (void) -{ - struct ptr_wrapper r; - r.ptr = malloc (sizeof (int)); - return r; -} - -struct ptr_wrapper -test_2 (void) -{ - struct ptr_wrapper r, s; - r.ptr = malloc (sizeof (int)); - s = r; - return s; -} - -struct nested -{ - struct ptr_wrapper w; -}; - -struct nested -test_3 (void) -{ - struct nested n; - n.w.ptr = malloc (sizeof (int)); - return n; -} - -void test_4 (void) -{ - struct ptr_wrapper r; - r.ptr = malloc (sizeof (int)); /* { dg-message "allocated here" } */ -} /* { dg-warning "leak of 'r.ptr'" } */ -/* { dg-bogus "leak of '<unknown>'" "unknown leak" { target *-*-* } .-1 } */ - -static struct ptr_wrapper __attribute__((noinline)) -called_by_test_5a (void) -{ - struct ptr_wrapper r; - r.ptr = malloc (sizeof (int)); /* { dg-message "allocated here" } */ - return r; -} - -void test_5a (void) -{ - struct ptr_wrapper q = called_by_test_5a (); -} /* { dg-warning "leak of 'q.ptr'" } */ - -static struct ptr_wrapper __attribute__((noinline)) -called_by_test_5b (void) -{ - struct ptr_wrapper r; - r.ptr = malloc (sizeof (int)); - return r; /* { dg-warning "leak of '<return-value>.ptr'" } */ - /* TODO: show the allocation point; improve above message. */ -} - -void test_5b (void) -{ - called_by_test_5b (); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/computed-goto-pr110529.c b/gcc/testsuite/gcc.dg/analyzer/computed-goto-pr110529.c new file mode 100644 index 0000000..988f94a --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/computed-goto-pr110529.c @@ -0,0 +1,27 @@ +/* C only: reuse of same array for int and label pointers. */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +void foo(int pc) { + int *arr[2] = {&&x, &&y}; + int var = 0; + __analyzer_dump_path (); /* { dg-message "path" } */ + + goto *arr[pc]; + +x: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 0); /* { dg-warning "TRUE" } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + arr[0] = (void *)0; + *arr[0] = 10086; /* { dg-warning "dereference of NULL" } */ + return; +y: + __analyzer_dump_path (); /* { dg-message "path" } */ + __analyzer_eval (pc == 1); /* { dg-warning "TRUE" "" { xfail *-*-* } } */ + /* { dg-bogus "FALSE" "" { target *-*-* } .-1 } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-2 } */ + return; +} + +int main() { foo(0); } diff --git a/gcc/testsuite/gcc.dg/analyzer/file-pr58237.c b/gcc/testsuite/gcc.dg/analyzer/file-pr58237.c index ecc7144..e186ce4 100644 --- a/gcc/testsuite/gcc.dg/analyzer/file-pr58237.c +++ b/gcc/testsuite/gcc.dg/analyzer/file-pr58237.c @@ -1,14 +1,19 @@ +/* C only: C++ exceptions double the fopen leak warnings. + Therefore this test has been duplicated as + c-c++-common/analyzer/file-pr58237-noexcept.c */ + typedef struct FILE FILE; FILE* fopen (const char*, const char*); int fclose (FILE*); char *fgets (char *, int, FILE *); -#define NULL ((void *)0) +#include "analyzer-decls.h" void f0(const char *str) { FILE * fp = fopen(str, "r"); /* { dg-message "opened here" } */ + // ideally warning should be located at the end of the function char buf[10]; fgets(buf, 10, fp); } /* { dg-warning "leak of FILE 'fp'" } */ @@ -16,6 +21,7 @@ void f0(const char *str) void f1(const char *str) { FILE * fp = fopen(str, "r"); /* { dg-message "opened here" } */ + // ideally warning should be located at the end of the function char buf[10]; while (fgets(buf, 10, fp) != NULL) @@ -27,6 +33,7 @@ void f1(const char *str) void f2(const char *str, int flag) { FILE * fp = fopen(str, "r"); /* { dg-message "opened here" } */ + // ideally warning should be located at the end of the function char buf[10]; while (fgets(buf, 10, fp) != NULL) @@ -65,7 +72,7 @@ void f4(const char *str) fclose(fp); } -void main(int argc, const char * argv[]) +int main(int argc, const char * argv[]) { FILE * fp = fopen(argv[0], "r"); char buf[10]; diff --git a/gcc/testsuite/gcc.dg/analyzer/fopen-1.c b/gcc/testsuite/gcc.dg/analyzer/fopen-1.c index e5b00e9..f59d9ef 100644 --- a/gcc/testsuite/gcc.dg/analyzer/fopen-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/fopen-1.c @@ -1,36 +1,9 @@ +/* C only: C++ FE fpermissive already emits an error for initializer + string too long. + C++ compatible parts have been moved into c-c++-common/analyzer/fopen-2.c */ + typedef struct FILE FILE; FILE *fopen (const char *pathname, const char *mode); -#define NULL ((void *)0) - -FILE * -test_passthrough (const char *pathname, const char *mode) -{ - return fopen (pathname, mode); -} - -FILE * -test_null_pathname (const char *pathname, const char *mode) -{ - return fopen (NULL, mode); -} - -FILE * -test_null_mode (const char *pathname) -{ - return fopen (pathname, NULL); -} - -FILE * -test_simple_r (void) -{ - return fopen ("foo.txt", "r"); -} - -FILE * -test_swapped_args (void) -{ - return fopen ("r", "foo.txt"); /* TODO: would be nice to detect this. */ -} FILE * test_unterminated_pathname (const char *mode) @@ -47,20 +20,3 @@ test_unterminated_mode (const char *filename) return fopen (filename, buf); /* { dg-warning "stack-based buffer over-read" } */ /* { dg-message "while looking for null terminator for argument 2 \\('&buf'\\) of 'fopen'..." "event" { target *-*-* } .-1 } */ } - -FILE * -test_uninitialized_pathname (const char *mode) -{ - char buf[10]; - return fopen (buf, mode); /* { dg-warning "use of uninitialized value 'buf\\\[0\\\]'" } */ - /* { dg-message "while looking for null terminator for argument 1 \\('&buf'\\) of 'fopen'..." "event" { target *-*-* } .-1 } */ -} - -FILE * -test_uninitialized_mode (const char *filename) -{ - char buf[10]; - return fopen (filename, buf); /* { dg-warning "use of uninitialized value 'buf\\\[0\\\]'" } */ - /* { dg-message "while looking for null terminator for argument 2 \\('&buf'\\) of 'fopen'..." "event" { target *-*-* } .-1 } */ -} - diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-1.c b/gcc/testsuite/gcc.dg/analyzer/inlining-1.c deleted file mode 100644 index a9797ea..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-1.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Verify that we can reconstruct fndecl and stack depth information - after early inlining. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ - -void foo (void *p) -{ - __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ - /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'foo', depth 2\\)" "1st free message" { target *-*-* } .-1 } */ - /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'foo', depth 2\\)" "2nd free message" { target *-*-* } .-2 } */ -} - -void bar (void *q) /* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'bar', depth 1\\)" } */ -{ - foo (q); /* { dg-message "\\(2\\) inlined call to 'foo' from 'bar' \\(fndecl 'bar', depth 1\\)" } */ - foo (q); /* { dg-message "\\(4\\) inlined call to 'foo' from 'bar' \\(fndecl 'bar', depth 1\\)" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-2.c b/gcc/testsuite/gcc.dg/analyzer/inlining-2.c deleted file mode 100644 index da06fa2..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-2.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Verify that we can reconstruct fndecl and stack depth information - after early inlining. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ - -static void __analyzer_foo (void *p) -{ - __builtin_free (p); /* { dg-message "\\(3\\) first 'free' here \\(fndecl '__analyzer_foo', depth 2\\)" "1st free message" } */ - - __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ - /* { dg-message "\\(4\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl '__analyzer_foo', depth 2\\)" "2nd free message" { target *-*-* } .-1 } */ -} - -void bar (void *q) /* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'bar', depth 1\\)" } */ -{ - __analyzer_foo (q); /* { dg-message "\\(2\\) inlined call to '__analyzer_foo' from 'bar' \\(fndecl 'bar', depth 1\\)" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-5.c b/gcc/testsuite/gcc.dg/analyzer/inlining-5.c deleted file mode 100644 index 5104be0..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-5.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Verify that we can reconstruct fndecl and stack depth information - after early inlining. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ - -static inline void -inner (void *p) -{ - __builtin_free (p); /* { dg-warning "double-'free' of 'r'" } */ - /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'inner', depth 3\\)" "2nd free message" { target *-*-* } .-1 } */ -} - -static inline void -middle (void *q) -{ - __builtin_free (q); /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'middle', depth 2\\)" "1st free message" } */ - inner (q); /* { dg-message "\\(4\\) inlined call to 'inner' from 'middle' \\(fndecl 'middle', depth 2\\)" } */ -} - -void -outer (void *r) /* { dg-message "\\(1\\) entry to 'outer' \\(fndecl 'outer', depth 1\\)" } */ -{ - middle (r); /* { dg-message "\\(2\\) inlined call to 'middle' from 'outer' \\(fndecl 'outer', depth 1\\)" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-7.c b/gcc/testsuite/gcc.dg/analyzer/inlining-7.c deleted file mode 100644 index fe04042..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-7.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Verify that we can reconstruct fndecl and stack depth information - after early inlining. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ - -/* We want the reconstructed call/return hierarchy to show - that two calls happen at depth_3, without any spurious events - popping the stack back any further. */ - -static inline void -depth_6 (void *p) -{ - __builtin_free (p); /* { dg-warning "double-'free' of 'p1'" "warning" } */ - /* { dg-message "\\(7\\) first 'free' here \\(fndecl 'depth_6', depth 6\\)" "1st free message" { target *-*-* } .-1 } */ - /* { dg-message "\\(11\\) second 'free' here; first 'free' was at \\(7\\) \\(fndecl 'depth_6', depth 6\\)" "2nd free message" { target *-*-* } .-2 } */ -} - -static inline void -depth_5 (void *p5) -{ - depth_6 (p5); /* { dg-message "\\(6\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'depth_5', depth 5\\)" "event 6" } */ - /* { dg-message "\\(10\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'depth_5', depth 5\\)" "event 10" { target *-*-* } .-1 } */ -} - -static inline void -depth_4 (void *p4) -{ - depth_5 (p4); /* { dg-message "\\(5\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'depth_4', depth 4\\)" "event 5" } */ - /* { dg-message "\\(9\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'depth_4', depth 4\\)" "event 9" { target *-*-* } .-1 } */ -} - -static inline void -depth_3 (void *p3) -{ - depth_4 (p3); /* { dg-message "\\(4\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'depth_3', depth 3\\)" } */ - depth_4 (p3); /* { dg-message "\\(8\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'depth_3', depth 3\\)" } */ -} - -static inline void -depth_2 (void *p2) -{ - depth_3 (p2); /* { dg-message "\\(3\\) inlined call to 'depth_3' from 'depth_2' \\(fndecl 'depth_2', depth 2\\)" } */ -} - -void -depth_1 (void *p1) /* { dg-message "\\(1\\) entry to 'depth_1' \\(fndecl 'depth_1', depth 1\\)" } */ -{ - depth_2 (p1); /* { dg-message "\\(2\\) inlined call to 'depth_2' from 'depth_1' \\(fndecl 'depth_1', depth 1\\)" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-4.c b/gcc/testsuite/gcc.dg/analyzer/malloc-4.c index 908bb28..058ae17 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-4.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-4.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-Wno-incompatible-pointer-types" } */ +/* C only: Wno-incompatible-pointer-types is not valid for C++. */ #include <stdlib.h> @@ -7,7 +8,7 @@ struct bar; void *hv (struct foo **tm) { void *p = __builtin_malloc (4); - *tm = p; + *tm = (struct foo *) p; if (!p) abort (); return p; @@ -16,5 +17,5 @@ void *hv (struct foo **tm) void a5 (void) { struct bar *qb = NULL; - hv (&qb); + hv ((struct foo **) &qb); } /* { dg-warning "leak of 'qb'" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c index a3cacc0..83eec29 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c @@ -1,5 +1,7 @@ /* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ /* { dg-enable-nn-line-numbers "" } */ +/* C only: C++ exceptions mess up events. Therefore this test has been duplicated + as c-c++-common/analyzer/malloc-paths-9-noexcept.c */ #include <stdlib.h> diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103892.c b/gcc/testsuite/gcc.dg/analyzer/pr103892.c index e9775b6..95d4b17 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr103892.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr103892.c @@ -1,5 +1,9 @@ /* { dg-additional-options "-O2" } */ +/* C only: C++ FE optimizes argstr_get_word completely away + and therefore the number of SN diminishes compared to C, + making the analysis bails out early. */ + extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__)); enum pipecmd_tag @@ -10,7 +14,7 @@ enum pipecmd_tag struct pipecmd { enum pipecmd_tag tag; - union { + union pipecmd_union_t { struct pipecmd_process { int argc; int argv_max; @@ -24,22 +28,30 @@ struct pipecmd { } u; }; +#ifdef __cplusplus +typedef pipecmd::pipecmd_union_t::pipecmd_process pipecmd_process_t; +typedef pipecmd::pipecmd_union_t::pipecmd_sequence pipecmd_sequence_t; +#else +typedef struct pipecmd_process pipecmd_process_t; +typedef struct pipecmd_sequence pipecmd_sequence_t; +#endif + static char *argstr_get_word (const char **argstr) { while (**argstr) { switch (**argstr) { case ' ': case '\t': - return (void *) 0; + return (char *) ((void *) 0); } } - return (void *) 0; + return (char *) ((void *) 0); } struct pipecmd *pipecmd_new_argstr (const char *argstr) { argstr_get_word (&argstr); - return (void *) 0; + return (struct pipecmd *) ((void *) 0); } void pipecmd_free (struct pipecmd *cmd) @@ -51,7 +63,7 @@ void pipecmd_free (struct pipecmd *cmd) switch (cmd->tag) { case PIPECMD_PROCESS: { - struct pipecmd_process *cmdp = &cmd->u.process; + pipecmd_process_t *cmdp = &cmd->u.process; for (i = 0; i < cmdp->argc; ++i) free (cmdp->argv[i]); @@ -61,7 +73,7 @@ void pipecmd_free (struct pipecmd *cmd) } case PIPECMD_SEQUENCE: { - struct pipecmd_sequence *cmds = &cmd->u.sequence; + pipecmd_sequence_t *cmds = &cmd->u.sequence; for (i = 0; i < cmds->ncommands; ++i) pipecmd_free (cmds->commands[i]); diff --git a/gcc/testsuite/gcc.dg/analyzer/pr109577.c b/gcc/testsuite/gcc.dg/analyzer/pr109577.c index a6af6f7..74d1629 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr109577.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr109577.c @@ -1,9 +1,13 @@ +/* C only: C++ exceptions cause a malloc leak after "safer" returns. + Therefore this test has been duplicated as + c-c++-common/analyzer/pr109577-noexcept.c */ + void *malloc (unsigned long); double * unsafe (unsigned long n) { - return malloc (n * sizeof (double)); + return (double *) malloc (n * sizeof (double)); } double * @@ -12,5 +16,5 @@ safer (unsigned long n) unsigned long nbytes; if (__builtin_mul_overflow (n, sizeof (double), &nbytes)) return 0; - return malloc (nbytes); + return (double *) malloc (nbytes); /* Exceptions enabled cause a leak here. */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c index c7b49d2..11d2b61 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c @@ -4,6 +4,10 @@ /* { dg-do "compile" } */ +/* C only: C++ exceptions cause another fopen leak warning to be emitted at line 54. + Therefore this test has been duplicated as + c-c++-common/analyzer/pr93355-localealias-feasibility-noexcept.c */ + /* Handle aliases for locale names. Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc. @@ -22,10 +26,10 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -/* Minimal version of system headers. */ +#include "../../gcc.dg/analyzer/analyzer-decls.h" +/* Minimal version of system headers. */ typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) typedef struct _IO_FILE FILE; extern FILE *fopen (const char *__restrict __filename, diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c index 459357c..ed19caf 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr99193-1.c @@ -1,5 +1,9 @@ /* { dg-additional-options "-Wno-analyzer-too-complex" } */ +/* C only: C++ exceptions cause a Wanalyzer-va-list-leak warning to be emitted + at the end of commandrf. Therefore this test has been duplicated as + c-c++-common/analyzer/pr99193-1-noexcept.c */ + /* Verify absence of false positive from -Wanalyzer-mismatching-deallocation on realloc(3). Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/command.c#L115 @@ -8,7 +12,7 @@ typedef __SIZE_TYPE__ size_t; typedef __builtin_va_list va_list; -#define NULL ((void *)0) +#include "analyzer-decls.h" extern void *malloc (size_t __size) __attribute__ ((__nothrow__ , __leaf__)) @@ -36,7 +40,7 @@ commandrf (char **stdoutput, char **stderror, unsigned flags, /* Collect the command line arguments into an array. */ i = 2; - argv = malloc (sizeof (char *) * i); + argv = (const char **) malloc (sizeof (char *) * i); if (argv == NULL) { perror ("malloc"); @@ -48,7 +52,7 @@ commandrf (char **stdoutput, char **stderror, unsigned flags, __builtin_va_start (args, name); while ((s = __builtin_va_arg (args, char *)) != NULL) { - const char **p = realloc (argv, sizeof (char *) * (++i)); /* { dg-bogus "'free'" } */ + const char **p = (const char **) realloc (argv, sizeof (char *) * (++i)); /* { dg-bogus "'free'" } */ if (p == NULL) { perror ("realloc"); __builtin_va_end (args); diff --git a/gcc/testsuite/gcc.dg/darwin-segaddr.c b/gcc/testsuite/gcc.dg/darwin-segaddr.c index 526db77..77112dd 100644 --- a/gcc/testsuite/gcc.dg/darwin-segaddr.c +++ b/gcc/testsuite/gcc.dg/darwin-segaddr.c @@ -2,6 +2,7 @@ /* { dg-do run { target *-*-darwin* } } */ /* { dg-options "-O0 -segaddr __TEST 0x200000 -fno-pie" { target { *-*-darwin* && { ! lp64 } } } } */ /* { dg-options "-O0 -segaddr __TEST 0x110000000 -fno-pie" { target { *-*-darwin* && lp64 } } } */ +/* { dg-prune-output "-no_pie is deprecated when targeting new OS versions" } */ extern void abort (); diff --git a/gcc/testsuite/gcc.dg/pie-7.c b/gcc/testsuite/gcc.dg/pie-7.c index e118a98..3879a6c 100644 --- a/gcc/testsuite/gcc.dg/pie-7.c +++ b/gcc/testsuite/gcc.dg/pie-7.c @@ -1,5 +1,6 @@ /* { dg-do run { target pie } } */ /* { dg-options "-fno-pie -no-pie" } */ +/* { dg-prune-output "-no_pie is deprecated when targeting new OS versions" } */ int main(void) { diff --git a/gcc/testsuite/gcc.dg/pr110875.c b/gcc/testsuite/gcc.dg/pr110875.c new file mode 100644 index 0000000..4d6ecbc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110875.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp2" } */ + +void foo(void); +static int a, b; +static int *c = &a, *d; +static unsigned e; +static short f; +static unsigned g(unsigned char h, char i) { return h + i; } +int main() { + d = &a; + int *j = d; + e = -27; + for (; e > 18; e = g(e, 6)) { + a = 0; + for (; a != -3; a--) { + if (0 != a ^ *j) + for (; b; b++) f = -f; + else if (*c) { + foo(); + break; + } + if (!(((e) >= 235) && ((e) <= 4294967269))) { + __builtin_unreachable(); + } + b = 0; + } + } +} + + +/* { dg-final { scan-tree-dump-not "foo" "vrp2" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-25.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-25.c new file mode 100644 index 0000000..b7a5bfd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-25.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-original" } */ +/* PR tree-optimization/111349 */ + +int f(); +int g(); + +int test1(int a, int b) +{ + return (a > b) ? ((a > b) ? a : b) : a; +} + +int test1_(int a, int b) +{ + return (b < a) ? ((a > b) ? a : b) : a; +} + +/* test1 and test1_ should be able to optimize to `return a;` during fold. */ +/* { dg-final { scan-tree-dump-times "return a;" 2 "original" } } */ +/* { dg-final { scan-tree-dump-not " MAX_EXPR " "original" } } */ +/* { dg-final { scan-tree-dump-times "return a" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmaxcmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/minmaxcmp-1.c new file mode 100644 index 0000000..0706c02 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmaxcmp-1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-original" } */ +/* PR tree-optimization/111346 */ + +int f(); +int g(); + +_Bool test1(int a, int b) +{ + return ((a > b) ? a : b) >= a; // return 1; +} +_Bool test1_(int a, int b) +{ + return a <= ((a > b) ? a : b); // return 1; +} +/* test1 and test1_ should be able to optimize to `return 1;` during fold. */ +/* { dg-final { scan-tree-dump-times "return 1;" 2 "original" } } */ +/* { dg-final { scan-tree-dump-not " MAX_EXPR " "original" } } */ + +_Bool test2(int a, int b) +{ + a = f(); + a = g(); + int t = a; + if (t < b) t = b; + return t >= a; // return 1; +} + +_Bool test2_(int a, int b) +{ + a = g(); + int t = a; + if (t < b) t = b; + return t >= a; // return 1; +} + +/* All of these should be optimized to just be the function calls and `return 1;` */ +/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " MAX_EXPR " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr111225.c b/gcc/testsuite/gcc.target/i386/pr111225.c new file mode 100644 index 0000000..5d92daf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr111225.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fsanitize=thread -mforce-drap -mavx512cd" } */ + +typedef long long __m256i __attribute__ ((__vector_size__ (32))); + +int foo (__m256i x, __m256i y) +{ + __m256i a = x & ~y; + return !__builtin_ia32_ptestz256 (a, a); +} + +int bar (__m256i x, __m256i y) +{ + __m256i a = ~x & y; + return !__builtin_ia32_ptestz256 (a, a); +} diff --git a/gcc/testsuite/gcc.target/i386/pr111306.c b/gcc/testsuite/gcc.target/i386/pr111306.c new file mode 100644 index 0000000..541725e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr111306.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavx512fp16 -mavx512vl" } */ +/* { dg-require-effective-target avx512fp16 } */ + +#define AVX512FP16 +#include "avx512f-helper.h" + +__attribute__((optimize("O2"),noipa)) +void func1(_Float16 *a, _Float16 *b, int n, _Float16 *c) { + __m512h rA = _mm512_loadu_ph(a); + for (int i = 0; i < n; i += 32) { + __m512h rB = _mm512_loadu_ph(b + i); + _mm512_storeu_ph(c + i, _mm512_fcmul_pch(rB, rA)); + } +} + +void +test_512 (void) +{ + int n = 32; + _Float16 a[n], b[n], c[n]; + _Float16 exp[n]; + for (int i = 1; i <= n; i++) { + a[i - 1] = i & 1 ? -i : i; + b[i - 1] = i; + } + + func1(a, b, n, c); + for (int i = 0; i < n / 32; i += 2) { + if (c[i] != a[i] * b[i] + a[i+1] * b[i+1] + || c[i+1] != a[i] * b[i+1] - a[i+1]*b[i]) + __builtin_abort (); + } +} + + diff --git a/gcc/testsuite/gcc.target/loongarch/memcpy-vec-1.c b/gcc/testsuite/gcc.target/loongarch/memcpy-vec-1.c new file mode 100644 index 0000000..8d9fedc --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/memcpy-vec-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -march=la464 -mno-strict-align" } */ +/* { dg-final { scan-assembler-times "xvst" 2 } } */ +/* { dg-final { scan-assembler-times "\tvst" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.d|stptr\\.d" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.w|stptr\\.w" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.h" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.b" 1 } } */ + +extern char a[], b[]; +void test() { __builtin_memcpy(a, b, 95); } diff --git a/gcc/testsuite/gcc.target/loongarch/memcpy-vec-2.c b/gcc/testsuite/gcc.target/loongarch/memcpy-vec-2.c new file mode 100644 index 0000000..6b28b88 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/memcpy-vec-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -march=la464 -mno-strict-align" } */ +/* { dg-final { scan-assembler-times "xvst" 2 } } */ +/* { dg-final { scan-assembler-times "\tvst" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.d|stptr\\.d" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.w|stptr\\.w" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.h" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.b" 1 } } */ + +typedef char __attribute__ ((vector_size (32), aligned (32))) vec; +extern vec a[], b[]; +void test() { __builtin_memcpy(a, b, 95); } diff --git a/gcc/testsuite/gcc.target/loongarch/memcpy-vec-3.c b/gcc/testsuite/gcc.target/loongarch/memcpy-vec-3.c new file mode 100644 index 0000000..db2ea51 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/memcpy-vec-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=la464 -mabi=lp64d -mstrict-align" } */ +/* { dg-final { scan-assembler-not "vst" } } */ + +extern char a[], b[]; +void test() { __builtin_memcpy(a, b, 32); } diff --git a/gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c b/gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c new file mode 100644 index 0000000..16163d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/mulw_d_wu.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "mulw.d.wu" } } */ + +__attribute__((noipa, noinline)) unsigned long +f(unsigned long a, unsigned long b) +{ + return (unsigned long)(unsigned int)a * (unsigned long)(unsigned int)b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c new file mode 100644 index 0000000..6f5c686 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/smuldi3_highpart.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-expand-all" } */ + +typedef int TI __attribute ((mode(TI))); +typedef int DI __attribute__((mode(DI))); + +DI +test (DI x, DI y) +{ + return ((TI)x * y) >> 64; +} + +/* { dg-final { scan-rtl-dump "highparttmp" "expand" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c new file mode 100644 index 0000000..c4dbf8af --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/smulsi3_highpart.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-expand-all" } */ + +typedef unsigned int DI __attribute__((mode(DI))); +typedef unsigned int SI __attribute__((mode(SI))); + +SI +f (SI x, SI y) +{ + return ((DI) x * y) >> 32; +} + +/* { dg-final { scan-rtl-dump "highparttmp" "expand" } } */ +/* { dg-final { scan-assembler "mulh\\.w" } } */ +/* { dg-final { scan-assembler-not "slli\\.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c new file mode 100644 index 0000000..e208803 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/umulsi3_highpart.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef unsigned int DI __attribute__((mode(DI))); +typedef unsigned int SI __attribute__((mode(SI))); + +SI +f (SI x, SI y) +{ + return ((DI) x * y) >> 32; +} + +/* { dg-final { scan-assembler "mulh\\.wu" } } */ +/* { dg-final { scan-assembler-not "slli\\.w" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c new file mode 100644 index 0000000..de4c472 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/fold-min-poly.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options " -march=rv64gcv_zvl128b -mabi=lp64d -O3 --param riscv-autovec-preference=scalable --param riscv-autovec-lmul=m1 -fno-vect-cost-model" } */ + +void foo1 (int* restrict a, int* restrict b, int n) +{ + for (int i = 0; i < 4; i += 1) + a[i] += b[i]; +} + +void foo2 (int* restrict a, int* restrict b, int n) +{ + for (int i = 0; i < 3; i += 1) + a[i] += b[i]; +} + +void foo3 (int* restrict a, int* restrict b, int n) +{ + for (int i = 0; i < 5; i += 1) + a[i] += b[i]; +} + +/* { dg-final { scan-assembler-not {\tcsrr\t} } } */ +/* { dg-final { scan-assembler {\tvsetivli\tzero,4,e32,m1,t[au],m[au]} } } */ +/* { dg-final { scan-assembler {\tvsetivli\tzero,3,e32,m1,t[au],m[au]} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c index 3571a32..34622ce 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c @@ -21,6 +21,6 @@ f (int8_t *restrict a, int8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1 or m2. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" "--param riscv-autovec-lmul=m8" } } } } */ /* { dg-final { scan-assembler {\tvid\.v} { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ /* { dg-final { scan-assembler {\tvand} { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c index 8c5c651..80c77ef 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c @@ -21,6 +21,6 @@ f (uint8_t *restrict a, uint8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1 or m2. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" "--param riscv-autovec-lmul=m8" } } } } */ /* { dg-final { scan-assembler {\tvid\.v} { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ /* { dg-final { scan-assembler-not {\tvmul} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c index 67dbada..50d06d5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */ #include <stdint-gcc.h> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c index fde54e1..75298bd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c @@ -21,4 +21,4 @@ f (int8_t *restrict a, int8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1 or m2. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" "--param riscv-autovec-lmul=m8" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c index 600699b..c1b31a4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c @@ -21,4 +21,4 @@ f (int8_t *restrict a, int8_t *restrict b, int n) /* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP when riscv-autovec-lmul=m1 or m2. */ -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" } } } } */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail { any-opts "--param riscv-autovec-lmul=m1" "--param riscv-autovec-lmul=m2" "--param riscv-autovec-lmul=m8" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-1.c new file mode 100644 index 0000000..537a032 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/compress-1.c" + +/* { dg-final { scan-assembler-times {\tvcompress\.vm} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-2.c new file mode 100644 index 0000000..e643147 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/compress-2.c" + +/* { dg-final { scan-assembler-times {\tvcompress\.vm} 5 } } */ +/* { dg-final { scan-assembler-times {\tvslideup} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-3.c new file mode 100644 index 0000000..5e87294 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-3.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/compress-3.c" + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 8 } } */ +/* { dg-final { scan-assembler-times {\tvslideup} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-4.c new file mode 100644 index 0000000..a4ceb62 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-4.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/compress-4.c" + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 11 } } */ +/* { dg-final { scan-assembler-times {\tvslideup} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-5.c new file mode 100644 index 0000000..f407027 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-5.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/compress-5.c" + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-6.c new file mode 100644 index 0000000..ffc0b8f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/compress-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/compress-6.c" + +/* { dg-final { scan-assembler-times {\tvcompress.vm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c index f3388a8..40224c6 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/div-1.c @@ -55,4 +55,4 @@ DEF_OP_VV (div, 512, int64_t, /) /* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 42 } } */ /* TODO: Ideally, we should make sure there is no "csrr vlenb". However, we still have 'csrr vlenb' for some cases since we don't support VLS mode conversion which are needed by division. */ -/* { dg-final { scan-assembler-times {csrr} 19 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-1.c new file mode 100644 index 0000000..9cbc845 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-1.c" + +/* { dg-final { scan-assembler-times {\tvmerge.vvm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-2.c new file mode 100644 index 0000000..e270db9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-2.c" + +/* { dg-final { scan-assembler-times {\tvmerge.vvm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-3.c new file mode 100644 index 0000000..033952f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-3.c" + +/* { dg-final { scan-assembler-times {\tvmerge.vvm} 11 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c new file mode 100644 index 0000000..62ed1a5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-4.c" + +/* dg-final scan-assembler-times {\tvmerge.vvm} 11 */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-5.c new file mode 100644 index 0000000..42fa2ec --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-5.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-5.c" + +/* { dg-final { scan-assembler-times {\tvmerge.vvm} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-6.c new file mode 100644 index 0000000..d5222f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-6.c" + +/* { dg-final { scan-assembler-times {\tvmerge.vvm} 5 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-7.c new file mode 100644 index 0000000..bd097f0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/merge-7.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/merge-7.c" + +/* { dg-final { scan-assembler-times {\tvmerge.vvm} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-1.c new file mode 100644 index 0000000..327913b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-1.c" + +/* { dg-final { scan-assembler-times {vrgather\.vi\tv[0-9]+,\s*v[0-9]+,\s*1} 31 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-2.c new file mode 100644 index 0000000..d562312 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-2.c" + +/* { dg-final { scan-assembler-times {vrgather\.vi\tv[0-9]+,\s*v[0-9]+,\s*31} 7 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-3.c new file mode 100644 index 0000000..87319e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-3.c" + +/* { dg-final { scan-assembler-times {vrgather\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c new file mode 100644 index 0000000..46cad8e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-4.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-4.c" + +/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 31 } } */ +/* { dg-final { scan-assembler-times {vrsub\.vi} 24 } } */ +/* { dg-final { scan-assembler-times {vrsub\.vx} 7 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-5.c new file mode 100644 index 0000000..3460315 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-5.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-5.c" + +/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 31 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-6.c new file mode 100644 index 0000000..a2a722f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-6.c" + +/* { dg-final { scan-assembler-times {vrgather\.vi\tv[0-9]+,\s*v[0-9]+,\s*1} 31 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-7.c new file mode 100644 index 0000000..b474ccf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/perm-7.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfhmin -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */ + +#include "../vls-vlmax/perm-7.c" + +/* { dg-final { scan-assembler-times {vrgather\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 31 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c index 98822b1..b34a349 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/shift-3.c @@ -55,4 +55,4 @@ DEF_OP_VV (shift, 512, int64_t, <<) /* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 41 } } */ /* TODO: Ideally, we should make sure there is no "csrr vlenb". However, we still have 'csrr vlenb' for some cases since we don't support VLS mode conversion which are needed by division. */ -/* { dg-final { scan-assembler-times {csrr} 18 } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c new file mode 100644 index 0000000..4645b9c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */ + +signed long extqi(signed char i) +{ + return --i; +} + +/* { dg-final { scan-assembler "th.ext\ta\[0-9\]+,a\[0-9\]+,7,0" } } */ +/* { dg-final { scan-assembler-not "th.ext\ta\[0-9\]+,a\[0-9\]+,15,0" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c new file mode 100644 index 0000000..2c9ebbc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */ + +signed long exthi(signed short i) +{ + return --i; +} + +/* { dg-final { scan-assembler "th.ext\ta\[0-9\]+,a\[0-9\]+,15,0" } } */ +/* { dg-final { scan-assembler-not "th.ext\ta\[0-9\]+,a\[0-9\]+,7,0" } } */ diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 3148ad3..3835d25 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -2070,7 +2070,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ /* We need BOUND <= LARGER. */ if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, - bound, larger))) + bound, arg_false))) return false; } else if (operand_equal_for_phi_arg_p (arg_false, smaller) @@ -2101,7 +2101,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ /* We need BOUND >= SMALLER. */ if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, - bound, smaller))) + bound, arg_false))) return false; } else @@ -2141,7 +2141,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ /* We need BOUND >= LARGER. */ if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, - bound, larger))) + bound, arg_true))) return false; } else if (operand_equal_for_phi_arg_p (arg_true, smaller) @@ -2168,7 +2168,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_ /* We need BOUND <= SMALLER. */ if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, - bound, smaller))) + bound, arg_true))) return false; } else diff --git a/gcc/value-range.h b/gcc/value-range.h index 6c5be36..da04be0 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -1158,7 +1158,7 @@ inline bool contains_zero_p (const irange &r) { if (r.undefined_p ()) - return true; + return false; wide_int zero = wi::zero (TYPE_PRECISION (r.type ())); return r.contains_p (zero); diff --git a/gcc/wide-int-print.cc b/gcc/wide-int-print.cc index a09ba02..f3a1871 100644 --- a/gcc/wide-int-print.cc +++ b/gcc/wide-int-print.cc @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "pretty-print.h" /* * public printing routines. @@ -138,3 +139,14 @@ print_hex (const wide_int_ref &wi, FILE *file) fputs (buf, file); } +/* Print larger precision wide_int. Not defined as inline in a header + together with pp_wide_int because XALLOCAVEC will make it uninlinable. */ + +void +pp_wide_int_large (pretty_printer *pp, const wide_int_ref &w, signop sgn) +{ + unsigned int prec = w.get_precision (); + char *buf = XALLOCAVEC (char, (prec + 3) / 4 + 3); + print_dec (w, buf, sgn); + pp_string (pp, buf); +} diff --git a/gcc/wide-int-print.h b/gcc/wide-int-print.h index 6d5fe7a..5aca037 100644 --- a/gcc/wide-int-print.h +++ b/gcc/wide-int-print.h @@ -34,5 +34,6 @@ extern void print_decu (const wide_int_ref &wi, char *buf); extern void print_decu (const wide_int_ref &wi, FILE *file); extern void print_hex (const wide_int_ref &wi, char *buf); extern void print_hex (const wide_int_ref &wi, FILE *file); +extern void pp_wide_int_large (pretty_printer *, const wide_int_ref &, signop); #endif /* WIDE_INT_PRINT_H */ |