diff options
author | Martin Liska <mliska@suse.cz> | 2021-06-25 10:51:49 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-06-25 10:51:49 +0200 |
commit | 99c8f78b7f201a4253989e897082774f7d300367 (patch) | |
tree | 34f69418f2a08e749f05ecc1d3f2318c7ec1739a | |
parent | 441aa2ce23465dbc6f0b108de3a72cb7f8003a9f (diff) | |
parent | 05516402f8eb8ec282a13fa1e38d9f9c5b3dd3e5 (diff) | |
download | gcc-99c8f78b7f201a4253989e897082774f7d300367.zip gcc-99c8f78b7f201a4253989e897082774f7d300367.tar.gz gcc-99c8f78b7f201a4253989e897082774f7d300367.tar.bz2 |
Merge branch 'master' into devel/sphinx
94 files changed, 1841 insertions, 524 deletions
@@ -1,3 +1,7 @@ +2021-06-24 prathamesh.kulkarni <prathamesh.kulkarni@linaro.org> + + * .gitignore: Add entry for cscope.out. + 2021-06-22 liuhongt <hongtao.liu@intel.com> * MAINTAINERS: Remove my Write After Approval entry. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 71534e4..d7ea100 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,234 @@ +2021-06-24 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/101189 + * gimple-range-fold.cc (fold_using_range::range_of_range_op): Pass + LHS range of condition to postfold routine. + (fold_using_range::postfold_gcond_edges): Only process the TRUE or + FALSE edge if the LHS range supports it being taken. + * gimple-range-fold.h (postfold_gcond_edges): Add range parameter. + +2021-06-24 Andrew MacLeod <amacleod@redhat.com> + + * value-relation.cc (equiv_oracle::dump): Do not dump NULL blocks. + (relation_oracle::find_relation_block): Check correct bitmap. + (relation_oracle::dump): Do not dump NULL blocks. + +2021-06-24 Andrew MacLeod <amacleod@redhat.com> + + * gimple-range-cache.cc (ranger_cache::propagate_cache): Call + range_on_edge instead of manually calculating. + +2021-06-24 Andrew MacLeod <amacleod@redhat.com> + + * range-op.cc: Fix comment. + +2021-06-24 Uroš Bizjak <ubizjak@gmail.com> + + PR target/89021 + * config/i386/i386-expand.c (ix86_expand_sse_unpack): + Handle V8QI and V4HI modes. + * config/i386/mmx.md (sse4_1_<any_extend:code>v4qiv4hi2): + New insn pattern. + (sse4_1_<any_extend:code>v4qiv4hi2): Ditto. + (mmxpackmode): New mode attribute. + (vec_pack_trunc_<mmxpackmode:mode>): New expander. + (mmxunpackmode): New mode attribute. + (vec_unpacks_lo_<mmxunpackmode:mode>): New expander. + (vec_unpacks_hi_<mmxunpackmode:mode>): Ditto. + (vec_unpacku_lo_<mmxunpackmode:mode>): Ditto. + (vec_unpacku_hi_<mmxunpackmode:mode>): Ditto. + * config/i386/i386.md (extsuffix): Move from ... + * config/i386/sse.md: ... here. + +2021-06-24 Eric Botcazou <ebotcazou@adacore.com> + + * dwarf2out.c (dwarf2out_assembly_start): Emit .file 0 marker here.. + (dwarf2out_finish): ...instead of here. + +2021-06-24 Eric Botcazou <ebotcazou@adacore.com> + + * configure.ac (--gdwarf-5 option): Use objdump instead of readelf. + (working --gdwarf-4/--gdwarf-5 for all sources): Likewise. + (--gdwarf-4 not refusing generated .debug_line): Adjust for Windows. + * configure: Regenerate. + +2021-06-24 Richard Biener <rguenther@suse.de> + + * config/i386/sse.md (vec_addsubv4df3, vec_addsubv2df3, + vec_addsubv8sf3, vec_addsubv4sf3): Merge into ... + (vec_addsub<mode>3): ... using a new addsub_cst mode attribute. + +2021-06-24 Richard Biener <rguenther@suse.de> + + * config/i386/sse.md (avx_addsubv4df3): Rename to + vec_addsubv4df3. + (avx_addsubv8sf3): Rename to vec_addsubv8sf3. + (sse3_addsubv2df3): Rename to vec_addsubv2df3. + (sse3_addsubv4sf3): Rename to vec_addsubv4sf3. + * config/i386/i386-builtin.def: Adjust. + * internal-fn.def (VEC_ADDSUB): New internal optab fn. + * optabs.def (vec_addsub_optab): New optab. + * tree-vect-slp-patterns.c (class addsub_pattern): New. + (slp_patterns): Add addsub_pattern. + * tree-vect-slp.c (vect_optimize_slp): Disable propagation + across CFN_VEC_ADDSUB. + * tree-vectorizer.h (vect_pattern::vect_pattern): Make + m_ops optional. + * doc/md.texi (vec_addsub<mode>3): Document. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/101170 + * df-scan.c (df_ref_record): For paradoxical big-endian SUBREGs + where regno + subreg_regno_offset wraps around use 0 as starting + regno. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/101172 + * stor-layout.c (finish_bitfield_representative): If nextf has + error_mark_node type, set repr type to error_mark_node too. + +2021-06-24 Ilya Leoshkevich <iii@linux.ibm.com> + + * config/s390/s390.c (s390_function_profiler): Ignore labelno + parameter. + * config/s390/s390.h (NO_PROFILE_COUNTERS): Define. + +2021-06-24 Richard Biener <rguenther@suse.de> + + * tree-vect-slp.c (vect_optimize_slp): Do not propagate + across operations that have different semantics on different + lanes. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + * tree.h (OMP_CLAUSE_MAP_IN_REDUCTION): Document meaning for OpenMP. + * gimplify.c (gimplify_scan_omp_clauses): For OpenMP map clauses + with OMP_CLAUSE_MAP_IN_REDUCTION flag partially defer gimplification + of non-decl OMP_CLAUSE_DECL. For OMP_CLAUSE_IN_REDUCTION on + OMP_TARGET user outer_ctx instead of ctx for placeholders and + initializer/combiner gimplification. + * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_MAP_IN_REDUCTION + on target constructs. + (lower_rec_input_clauses): Likewise. + (lower_omp_target): Likewise. + * omp-expand.c (expand_omp_target): Temporarily ignore nowait clause + on target if in_reduction is present. + +2021-06-24 Kewen Lin <linkw@linux.ibm.com> + + * tree-predcom.c (class pcom_worker): New class. + (release_chain): Renamed to... + (pcom_worker::release_chain): ...this. + (release_chains): Renamed to... + (pcom_worker::release_chains): ...this. + (aff_combination_dr_offset): Renamed to... + (pcom_worker::aff_combination_dr_offset): ...this. + (determine_offset): Renamed to... + (pcom_worker::determine_offset): ...this. + (class comp_ptrs): New class. + (split_data_refs_to_components): Renamed to... + (pcom_worker::split_data_refs_to_components): ...this, + and update with class comp_ptrs. + (suitable_component_p): Renamed to... + (pcom_worker::suitable_component_p): ...this. + (filter_suitable_components): Renamed to... + (pcom_worker::filter_suitable_components): ...this. + (valid_initializer_p): Renamed to... + (pcom_worker::valid_initializer_p): ...this. + (find_looparound_phi): Renamed to... + (pcom_worker::find_looparound_phi): ...this. + (add_looparound_copies): Renamed to... + (pcom_worker::add_looparound_copies): ...this. + (determine_roots_comp): Renamed to... + (pcom_worker::determine_roots_comp): ...this. + (determine_roots): Renamed to... + (pcom_worker::determine_roots): ...this. + (single_nonlooparound_use): Renamed to... + (pcom_worker::single_nonlooparound_use): ...this. + (remove_stmt): Renamed to... + (pcom_worker::remove_stmt): ...this. + (execute_pred_commoning_chain): Renamed to... + (pcom_worker::execute_pred_commoning_chain): ...this. + (execute_pred_commoning): Renamed to... + (pcom_worker::execute_pred_commoning): ...this. + (struct epcc_data): New member worker. + (execute_pred_commoning_cbck): Call execute_pred_commoning + with pcom_worker pointer. + (find_use_stmt): Renamed to... + (pcom_worker::find_use_stmt): ...this. + (find_associative_operation_root): Renamed to... + (pcom_worker::find_associative_operation_root): ...this. + (find_common_use_stmt): Renamed to... + (pcom_worker::find_common_use_stmt): ...this. + (combinable_refs_p): Renamed to... + (pcom_worker::combinable_refs_p): ...this. + (reassociate_to_the_same_stmt): Renamed to... + (pcom_worker::reassociate_to_the_same_stmt): ...this. + (stmt_combining_refs): Renamed to... + (pcom_worker::stmt_combining_refs): ...this. + (combine_chains): Renamed to... + (pcom_worker::combine_chains): ...this. + (try_combine_chains): Renamed to... + (pcom_worker::try_combine_chains): ...this. + (prepare_initializers_chain): Renamed to... + (pcom_worker::prepare_initializers_chain): ...this. + (prepare_initializers): Renamed to... + (pcom_worker::prepare_initializers): ...this. + (prepare_finalizers_chain): Renamed to... + (pcom_worker::prepare_finalizers_chain): ...this. + (prepare_finalizers): Renamed to... + (pcom_worker::prepare_finalizers): ...this. + (tree_predictive_commoning_loop): Renamed to... + (pcom_worker::tree_predictive_commoning_loop): ...this, adjust + some calls and remove some cleanup code. + (tree_predictive_commoning): Adjusted to use pcom_worker instance. + (static variable looparound_phis): Remove. + (static variable name_expansions): Remove. + +2021-06-24 Richard Biener <rguenther@suse.de> + + * tree-vect-slp.c (slpg_vertex): New struct. + (vect_slp_build_vertices): Adjust. + (vect_optimize_slp): Likewise. Maintain an outgoing permute + and a materialized one. + +2021-06-24 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101105 + * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list): + Only ignore steps when they are equal or scalar order is preserved. + +2021-06-24 liuhongt <hongtao.liu@intel.com> + + PR target/98434 + * config/i386/i386-expand.c (ix86_expand_vec_interleave): + Adjust comments for ix86_expand_vecop_qihi2. + (ix86_expand_vecmul_qihi): Renamed to .. + (ix86_expand_vecop_qihi2): Adjust function prototype to + support shift operation, add static to definition. + (ix86_expand_vec_shift_qihi_constant): Add static to definition. + (ix86_expand_vecop_qihi): Call ix86_expand_vecop_qihi2 and + ix86_expand_vec_shift_qihi_constant. + * config/i386/i386-protos.h (ix86_expand_vecmul_qihi): Deleted. + (ix86_expand_vec_shift_qihi_constant): Deleted. + * config/i386/sse.md (VI12_256_512_AVX512VL): New mode + iterator. + (mulv8qi3): Call ix86_expand_vecop_qihi directly, add + condition TARGET_64BIT. + (mul<mode>3): Ditto. + (<insn><mode>3): Ditto. + (vlshr<mode>3): Extend to support avx512 vlshr. + (v<insn><mode>3): New expander for + vashr/vlshr/vashl. + (v<insn>v8qi3): Ditto. + (vashrv8hi3<mask_name>): Renamed to .. + (vashr<mode>3): And extend to support V16QImode for avx512. + (vashrv16qi3): Deleted. + (vashrv2di3<mask_name>): Extend expander to support avx512 + instruction. + 2021-06-23 Dimitar Dimitrov <dimitar@dinux.eu> * doc/lto.texi (Design Overview): Update that slim objects are diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index fb7726b..ed06b62 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210624 +20210625 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d32de22..3d8c2b9 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1698,6 +1698,7 @@ OBJS = \ vmsdbgout.o \ vr-values.o \ vtable-verify.o \ + warning-control.o \ web.o \ wide-int.o \ wide-int-print.o \ @@ -1709,8 +1710,8 @@ OBJS = \ # Objects in libcommon.a, potentially used by all host binaries and with # no target dependencies. -OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \ - diagnostic-format-json.o json.o \ +OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \ + diagnostic-show-locus.o diagnostic-format-json.o json.o \ edit-context.o \ pretty-print.o intl.o \ sbitmap.o \ @@ -2650,6 +2651,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/ipa-modref.h $(srcdir)/ipa-modref.c \ $(srcdir)/ipa-modref-tree.h \ $(srcdir)/signop.h \ + $(srcdir)/diagnostic-spec.h $(srcdir)/diagnostic-spec.c \ $(srcdir)/dwarf2out.h \ $(srcdir)/dwarf2asm.c \ $(srcdir)/dwarf2cfi.c \ diff --git a/gcc/builtins.c b/gcc/builtins.c index 855ad1e..e5e3938 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1095,7 +1095,9 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, bool exact /* = false */, const wide_int bndrng[2] /* = NULL */) { - if ((expr && TREE_NO_WARNING (expr)) || TREE_NO_WARNING (arg)) + const opt_code opt = OPT_Wstringop_overread; + if ((expr && warning_suppressed_p (expr, opt)) + || warning_suppressed_p (arg, opt)) return; loc = expansion_point_location_if_in_system_header (loc); @@ -1123,14 +1125,14 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, if (bndrng) { if (wi::ltu_p (maxsiz, bndrng[0])) - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%K%qD specified bound %s exceeds " "maximum object size %E", expr, func, bndstr, maxobjsize); else { bool maybe = wi::to_wide (size) == bndrng[0]; - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, exact ? G_("%K%qD specified bound %s exceeds " "the size %E of unterminated array") @@ -1145,7 +1147,7 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, } } else - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%K%qD argument missing terminating nul", expr, func); } @@ -1154,14 +1156,14 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, if (bndrng) { if (wi::ltu_p (maxsiz, bndrng[0])) - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%qs specified bound %s exceeds " "maximum object size %E", fname, bndstr, maxobjsize); else { bool maybe = wi::to_wide (size) == bndrng[0]; - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, exact ? G_("%qs specified bound %s exceeds " "the size %E of unterminated array") @@ -1176,7 +1178,7 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, } } else - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%qs argument missing terminating nul", fname); } @@ -1185,9 +1187,9 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, { inform (DECL_SOURCE_LOCATION (decl), "referenced argument declared here"); - TREE_NO_WARNING (arg) = 1; + suppress_warning (arg, opt); if (expr) - TREE_NO_WARNING (expr) = 1; + suppress_warning (expr, opt); } } @@ -1445,14 +1447,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize) { /* Suppress multiple warnings for propagated constant strings. */ if (only_value != 2 - && !TREE_NO_WARNING (arg) + && !warning_suppressed_p (arg, OPT_Warray_bounds) && warning_at (loc, OPT_Warray_bounds, "offset %qwi outside bounds of constant string", eltoff)) { if (decl) inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl); - TREE_NO_WARNING (arg) = 1; + suppress_warning (arg, OPT_Warray_bounds); } return NULL_TREE; } @@ -3947,10 +3949,10 @@ determine_block_size (tree len, rtx len_rtx, accessing an object with SIZE. */ static bool -maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, +maybe_warn_for_bound (opt_code opt, location_t loc, tree exp, tree func, tree bndrng[2], tree size, const access_data *pad = NULL) { - if (!bndrng[0] || TREE_NO_WARNING (exp)) + if (!bndrng[0] || warning_suppressed_p (exp, opt)) return false; tree maxobjsize = max_object_size (); @@ -4042,7 +4044,7 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, inform (EXPR_LOCATION (pad->src.ref), "source object allocated here"); } - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, opt); } return warned; @@ -4089,14 +4091,14 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, return false; else if (tree_int_cst_equal (bndrng[0], bndrng[1])) warned = (func - ? warning_at (loc, OPT_Wstringop_overflow_, + ? warning_at (loc, opt, (maybe ? G_("%K%qD specified bound %E may exceed " "destination size %E") : G_("%K%qD specified bound %E exceeds " "destination size %E")), exp, func, bndrng[0], size) - : warning_at (loc, OPT_Wstringop_overflow_, + : warning_at (loc, opt, (maybe ? G_("%Kspecified bound %E may exceed " "destination size %E") @@ -4105,14 +4107,14 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, exp, bndrng[0], size)); else warned = (func - ? warning_at (loc, OPT_Wstringop_overflow_, + ? warning_at (loc, opt, (maybe ? G_("%K%qD specified bound [%E, %E] may exceed " "destination size %E") : G_("%K%qD specified bound [%E, %E] exceeds " "destination size %E")), exp, func, bndrng[0], bndrng[1], size) - : warning_at (loc, OPT_Wstringop_overflow_, + : warning_at (loc, opt, (maybe ? G_("%Kspecified bound [%E, %E] exceeds " "destination size %E") @@ -4131,7 +4133,7 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, inform (EXPR_LOCATION (pad->dst.ref), "destination object allocated here"); } - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, opt); } return warned; @@ -4357,7 +4359,7 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2], exp, range[0], range[1], size)); if (warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return warned; } @@ -4400,7 +4402,7 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2], exp, range[0], range[1], size)); if (warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return warned; } @@ -4779,8 +4781,10 @@ check_access (tree exp, tree dstwrite, && tree_fits_uhwi_p (dstwrite) && tree_int_cst_lt (dstwrite, range[0])))) { - if (TREE_NO_WARNING (exp) - || (pad && pad->dst.ref && TREE_NO_WARNING (pad->dst.ref))) + const opt_code opt = OPT_Wstringop_overflow_; + if (warning_suppressed_p (exp, opt) + || (pad && pad->dst.ref + && warning_suppressed_p (pad->dst.ref, opt))) return false; location_t loc = tree_inlined_location (exp); @@ -4791,12 +4795,12 @@ check_access (tree exp, tree dstwrite, and a source of unknown length. The call will write at least one byte past the end of the destination. */ warned = (func - ? warning_at (loc, OPT_Wstringop_overflow_, + ? warning_at (loc, opt, "%K%qD writing %E or more bytes into " "a region of size %E overflows " "the destination", exp, func, range[0], dstsize) - : warning_at (loc, OPT_Wstringop_overflow_, + : warning_at (loc, opt, "%Kwriting %E or more bytes into " "a region of size %E overflows " "the destination", @@ -4817,7 +4821,7 @@ check_access (tree exp, tree dstwrite, if (warned) { - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overflow_); if (pad) pad->dst.inform_access (pad->mode); } @@ -4852,9 +4856,9 @@ check_access (tree exp, tree dstwrite, if (size != maxobjsize && tree_int_cst_lt (size, range[0])) { - int opt = (dstwrite || mode != access_read_only - ? OPT_Wstringop_overflow_ - : OPT_Wstringop_overread); + opt_code opt = (dstwrite || mode != access_read_only + ? OPT_Wstringop_overflow_ + : OPT_Wstringop_overread); maybe_warn_for_bound (opt, loc, exp, func, range, size, pad); return false; } @@ -4890,19 +4894,21 @@ check_access (tree exp, tree dstwrite, if (overread) { - if (TREE_NO_WARNING (exp) - || (srcstr && TREE_NO_WARNING (srcstr)) - || (pad && pad->src.ref && TREE_NO_WARNING (pad->src.ref))) + const opt_code opt = OPT_Wstringop_overread; + if (warning_suppressed_p (exp, opt) + || (srcstr && warning_suppressed_p (srcstr, opt)) + || (pad && pad->src.ref + && warning_suppressed_p (pad->src.ref, opt))) return false; location_t loc = tree_inlined_location (exp); const bool read = mode == access_read_only || mode == access_read_write; const bool maybe = pad && pad->dst.parmarray; - if (warn_for_access (loc, func, exp, OPT_Wstringop_overread, range, - slen, false, read, maybe)) + if (warn_for_access (loc, func, exp, opt, range, slen, false, read, + maybe)) { - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, opt); if (pad) pad->src.inform_access (access_read_only); } @@ -7462,8 +7468,7 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, /* Expand the library call ourselves using a stabilized argument list to avoid re-evaluating the function's arguments twice. */ tree call = build_call_nofold_loc (loc, fndecl, 3, arg1, arg2, len); - if (TREE_NO_WARNING (exp)) - TREE_NO_WARNING (call) = true; + copy_warning (call, exp); gcc_assert (TREE_CODE (call) == CALL_EXPR); CALL_EXPR_TAILCALL (call) = CALL_EXPR_TAILCALL (exp); return expand_call (call, target, target == const0_rtx); @@ -13898,10 +13903,11 @@ maybe_emit_free_warning (tree exp) else { tree alloc_decl = gimple_call_fndecl (def_stmt); - int opt = (DECL_IS_OPERATOR_NEW_P (alloc_decl) - || DECL_IS_OPERATOR_DELETE_P (dealloc_decl) - ? OPT_Wmismatched_new_delete - : OPT_Wmismatched_dealloc); + const opt_code opt = + (DECL_IS_OPERATOR_NEW_P (alloc_decl) + || DECL_IS_OPERATOR_DELETE_P (dealloc_decl) + ? OPT_Wmismatched_new_delete + : OPT_Wmismatched_dealloc); warned = warning_at (loc, opt, "%K%qD called on pointer returned " "from a mismatched allocation " @@ -14012,7 +14018,7 @@ fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs) { ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); SET_EXPR_LOCATION (ret, loc); - TREE_NO_WARNING (ret) = 1; + suppress_warning (ret); return ret; } return NULL_TREE; diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index ba218e6..1521f2d 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + * c-common.h (enum c_omp_region_type): Add C_ORT_TARGET and + C_ORT_OMP_TARGET. + * c-omp.c (c_omp_split_clauses): For OMP_CLAUSE_IN_REDUCTION on + combined target constructs also add map (always, tofrom:) clause. + 2021-06-15 Robin Dapp <rdapp@linux.ibm.com> * c-attribs.c (common_handle_aligned_attribute): Remove short diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index c4eb2b1..681fcc9 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -3375,7 +3375,6 @@ pointer_int_sum (location_t loc, enum tree_code resultcode, tree c_wrap_maybe_const (tree expr, bool non_const) { - bool nowarning = TREE_NO_WARNING (expr); location_t loc = EXPR_LOCATION (expr); /* This should never be called for C++. */ @@ -3386,8 +3385,6 @@ c_wrap_maybe_const (tree expr, bool non_const) STRIP_TYPE_NOPS (expr); expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr); C_MAYBE_CONST_EXPR_NON_CONST (expr) = non_const; - if (nowarning) - TREE_NO_WARNING (expr) = 1; protected_set_expr_location (expr, loc); return expr; @@ -3633,12 +3630,12 @@ c_common_truthvalue_conversion (location_t location, tree expr) break; case MODIFY_EXPR: - if (!TREE_NO_WARNING (expr) + if (!warning_suppressed_p (expr, OPT_Wparentheses) && warn_parentheses && warning_at (location, OPT_Wparentheses, "suggest parentheses around assignment used as " "truth value")) - TREE_NO_WARNING (expr) = 1; + suppress_warning (expr, OPT_Wparentheses); break; case CONST_DECL: @@ -6019,7 +6016,7 @@ check_function_arguments_recurse (void (*callback) void *ctx, tree param, unsigned HOST_WIDE_INT param_num) { - if (TREE_NO_WARNING (param)) + if (warning_suppressed_p (param)) return; if (CONVERT_EXPR_P (param) diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c index 39c969d..0d38b70 100644 --- a/gcc/c-family/c-gimplify.c +++ b/gcc/c-family/c-gimplify.c @@ -713,7 +713,7 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, && !TREE_STATIC (DECL_EXPR_DECL (*expr_p)) && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p)) && !warn_init_self) - TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1; + suppress_warning (DECL_EXPR_DECL (*expr_p), OPT_Winit_self); break; case PREINCREMENT_EXPR: diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index cd3c99e..3495959 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -155,7 +155,7 @@ overflow_warning (location_t loc, tree value, tree expr) value); if (warned) - TREE_NO_WARNING (value) = 1; + suppress_warning (value, OPT_Woverflow); } /* Helper function for walk_tree. Unwrap C_MAYBE_CONST_EXPRs in an expression @@ -219,7 +219,7 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, && INTEGRAL_TYPE_P (TREE_TYPE (op_left)) && !CONSTANT_CLASS_P (stripped_op_left) && TREE_CODE (stripped_op_left) != CONST_DECL - && !TREE_NO_WARNING (op_left) + && !warning_suppressed_p (op_left, OPT_Wlogical_op) && TREE_CODE (op_right) == INTEGER_CST && !integer_zerop (op_right) && !integer_onep (op_right)) @@ -234,7 +234,7 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, = warning_at (location, OPT_Wlogical_op, "logical %<and%> applied to non-boolean constant"); if (warned) - TREE_NO_WARNING (op_left) = true; + suppress_warning (op_left, OPT_Wlogical_op); return; } @@ -588,7 +588,7 @@ bool warn_if_unused_value (const_tree exp, location_t locus, bool quiet) { restart: - if (TREE_USED (exp) || TREE_NO_WARNING (exp)) + if (TREE_USED (exp) || warning_suppressed_p (exp, OPT_Wunused_value)) return false; /* Don't warn about void constructs. This includes casting to void, @@ -2410,7 +2410,7 @@ do_warn_unused_parameter (tree fn) decl; decl = DECL_CHAIN (decl)) if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl) - && !TREE_NO_WARNING (decl)) + && !warning_suppressed_p (decl, OPT_Wunused_parameter)) warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wunused_parameter, "unused parameter %qD", decl); } diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 5751a37..c38b665 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,30 @@ +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR c/101176 + * c-parser.c (c_parser_has_attribute_expression): Set source range for + the result. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR c/101171 + * c-typeck.c (build_c_cast): Don't call note_integer_operands on + error_mark_node. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + * c-parser.c (omp_split_clauses): Pass C_ORT_OMP_TARGET instead of + C_ORT_OMP for clauses on target construct. + (OMP_TARGET_CLAUSE_MASK): Add in_reduction clause. + (c_parser_omp_target): For non-combined target add + map (always, tofrom:) clauses for OMP_CLAUSE_IN_REDUCTION. Pass + C_ORT_OMP_TARGET to c_finish_omp_clauses. + * c-typeck.c (handle_omp_array_sections): Adjust ort handling + for addition of C_ORT_OMP_TARGET and simplify, mapping clauses are + never present on C_ORT_*DECLARE_SIMD. + (c_finish_omp_clauses): Likewise. Handle OMP_CLAUSE_IN_REDUCTION + on C_ORT_OMP_TARGET, set OMP_CLAUSE_MAP_IN_REDUCTION on + corresponding map clauses. + 2021-06-21 Jakub Jelinek <jakub@redhat.com> PR inline-asm/100785 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 7cd13a5..983d65e 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -1295,7 +1295,7 @@ pop_scope (void) case VAR_DECL: /* Warnings for unused variables. */ if ((!TREE_USED (p) || !DECL_READ_P (p)) - && !TREE_NO_WARNING (p) + && !warning_suppressed_p (p, OPT_Wunused_but_set_variable) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) @@ -2159,8 +2159,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl) - || TREE_NO_WARNING (newdecl) - || TREE_NO_WARNING (olddecl)) + || warning_suppressed_p (newdecl, OPT_Wpedantic) + || warning_suppressed_p (olddecl, OPT_Wpedantic)) return true; /* Allow OLDDECL to continue in use. */ if (variably_modified_type_p (newtype, NULL)) @@ -2956,7 +2956,7 @@ duplicate_decls (tree newdecl, tree olddecl) if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype)) { /* Avoid `unused variable' and other warnings for OLDDECL. */ - TREE_NO_WARNING (olddecl) = 1; + suppress_warning (olddecl, OPT_Wunused); return false; } @@ -7543,10 +7543,7 @@ grokdeclarator (const struct c_declarator *declarator, FIELD_DECL, declarator->u.id.id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; if (bitfield && !declarator->u.id.id) - { - TREE_NO_WARNING (decl) = 1; - DECL_PADDING_P (decl) = 1; - } + DECL_PADDING_P (decl) = 1; if (size_varies) C_DECL_VARIABLE_SIZE (decl) = 1; @@ -10244,7 +10241,7 @@ finish_function (location_t end_loc) && targetm.warn_func_return (fndecl) && warning (OPT_Wreturn_type, "no return statement in function returning non-void")) - TREE_NO_WARNING (fndecl) = 1; + suppress_warning (fndecl, OPT_Wreturn_type); /* Complain about parameters that are only set, but never otherwise used. */ if (warn_unused_but_set_parameter) @@ -10259,7 +10256,7 @@ finish_function (location_t end_loc) && !DECL_READ_P (decl) && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl) - && !TREE_NO_WARNING (decl)) + && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter)) warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wunused_but_set_parameter, "parameter %qD set but not used", decl); @@ -12126,19 +12123,20 @@ c_write_global_declarations_1 (tree globals) { if (C_DECL_USED (decl)) { + /* TODO: Add OPT_Wundefined-inline. */ if (pedwarn (input_location, 0, "%q+F used but never defined", decl)) - TREE_NO_WARNING (decl) = 1; + suppress_warning (decl /* OPT_Wundefined-inline. */); } /* For -Wunused-function warn about unused static prototypes. */ else if (warn_unused_function && ! DECL_ARTIFICIAL (decl) - && ! TREE_NO_WARNING (decl)) + && ! warning_suppressed_p (decl, OPT_Wunused_function)) { if (warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl)) - TREE_NO_WARNING (decl) = 1; + suppress_warning (decl, OPT_Wunused_function); } } diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 68c74cc..0ebcb46 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -154,7 +154,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, tree orig_op0, orig_op1, orig_op2; bool op0_const = true, op1_const = true, op2_const = true; bool op0_const_self = true, op1_const_self = true, op2_const_self = true; - bool nowarning = TREE_NO_WARNING (expr); + bool nowarning = warning_suppressed_p (expr, OPT_Woverflow); bool unused_p; bool op0_lval = false; source_range old_range; @@ -670,13 +670,13 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, out: /* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks have been done by this point, so remove them again. */ - nowarning |= TREE_NO_WARNING (ret); + nowarning |= warning_suppressed_p (ret, OPT_Woverflow); STRIP_TYPE_NOPS (ret); - if (nowarning && !TREE_NO_WARNING (ret)) + if (nowarning && !warning_suppressed_p (ret, OPT_Woverflow)) { if (!CAN_HAVE_LOCATION_P (ret)) ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); - TREE_NO_WARNING (ret) = 1; + suppress_warning (ret, OPT_Woverflow); } if (ret != expr) { diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index c0f7020..3922b56 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -7558,7 +7558,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after, ret.original_code = MODIFY_EXPR; else { - TREE_NO_WARNING (ret.value) = 1; + suppress_warning (ret.value, OPT_Wparentheses); ret.original_code = ERROR_MARK; } ret.original_type = NULL; @@ -8406,6 +8406,7 @@ c_parser_has_attribute_expression (c_parser *parser) { gcc_assert (c_parser_next_token_is_keyword (parser, RID_BUILTIN_HAS_ATTRIBUTE)); + location_t start = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); c_inhibit_evaluation_warnings++; @@ -8484,6 +8485,7 @@ c_parser_has_attribute_expression (c_parser *parser) parser->translate_strings_p = save_translate_strings_p; + location_t finish = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) c_parser_consume_token (parser); else @@ -8512,6 +8514,7 @@ c_parser_has_attribute_expression (c_parser *parser) else result.value = boolean_false_node; + set_c_expr_source_range (&result, start, finish); return result; } @@ -9085,7 +9088,7 @@ c_parser_postfix_expression (c_parser *parser) c_parser_consume_token (parser); expr = c_parser_expression (parser); if (TREE_CODE (expr.value) == MODIFY_EXPR) - TREE_NO_WARNING (expr.value) = 1; + suppress_warning (expr.value, OPT_Wparentheses); if (expr.original_code != C_MAYBE_CONST_EXPR && expr.original_code != SIZEOF_EXPR) expr.original_code = ERROR_MARK; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index d0d36c3..5349ef1 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -1911,8 +1911,7 @@ array_to_pointer_conversion (location_t loc, tree exp) STRIP_TYPE_NOPS (exp); - if (TREE_NO_WARNING (orig_exp)) - TREE_NO_WARNING (exp) = 1; + copy_warning (exp, orig_exp); ptrtype = build_pointer_type (restype); @@ -1945,8 +1944,7 @@ function_to_pointer_conversion (location_t loc, tree exp) STRIP_TYPE_NOPS (exp); - if (TREE_NO_WARNING (orig_exp)) - TREE_NO_WARNING (exp) = 1; + copy_warning (exp, orig_exp); return build_unary_op (loc, ADDR_EXPR, exp, false); } @@ -2055,8 +2053,7 @@ default_function_array_conversion (location_t loc, struct c_expr exp) exp.value = TREE_OPERAND (exp.value, 0); } - if (TREE_NO_WARNING (orig_exp)) - TREE_NO_WARNING (exp.value) = 1; + copy_warning (exp.value, orig_exp); lvalue_array_p = !not_lvalue && lvalue_p (exp.value); if (!flag_isoc99 && !lvalue_array_p) @@ -2154,7 +2151,8 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp, tmp = create_tmp_var_raw (nonatomic_type); tmp_addr = build_unary_op (loc, ADDR_EXPR, tmp, false); TREE_ADDRESSABLE (tmp) = 1; - TREE_NO_WARNING (tmp) = 1; + /* Do not disable warnings for TMP even though it's artificial. + -Winvalid-memory-model depends on it. */ /* Issue __atomic_load (&expr, &tmp, SEQ_CST); */ fndecl = builtin_decl_explicit (BUILT_IN_ATOMIC_LOAD); @@ -2251,8 +2249,7 @@ default_conversion (tree exp) orig_exp = exp; STRIP_TYPE_NOPS (exp); - if (TREE_NO_WARNING (orig_exp)) - TREE_NO_WARNING (exp) = 1; + copy_warning (exp, orig_exp); if (code == VOID_TYPE) { @@ -2616,7 +2613,7 @@ build_indirect_ref (location_t loc, tree ptr, ref_operator errstring) if (warn_strict_aliasing > 2) if (strict_aliasing_warning (EXPR_LOCATION (pointer), type, TREE_OPERAND (pointer, 0))) - TREE_NO_WARNING (pointer) = 1; + suppress_warning (pointer, OPT_Wstrict_aliasing_); } if (TREE_CODE (pointer) == ADDR_EXPR @@ -3218,7 +3215,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc, /* If -Wnonnull warning has been diagnosed, avoid diagnosing it again later. */ if (warned_p && TREE_CODE (result) == CALL_EXPR) - TREE_NO_WARNING (result) = 1; + suppress_warning (result, OPT_Wnonnull); /* In this improbable scenario, a nested function returns a VM type. Create a TARGET_EXPR so that the call always has a LHS, much as @@ -4167,7 +4164,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, TYPE_UNQUALIFIED); val = create_tmp_var_raw (nonatomic_rhs_type); TREE_ADDRESSABLE (val) = 1; - TREE_NO_WARNING (val) = 1; + suppress_warning (val); rhs = build4 (TARGET_EXPR, nonatomic_rhs_type, val, rhs, NULL_TREE, NULL_TREE); TREE_SIDE_EFFECTS (rhs) = 1; @@ -4268,7 +4265,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, newval = create_tmp_var_raw (nonatomic_lhs_type); TREE_ADDRESSABLE (newval) = 1; - TREE_NO_WARNING (newval) = 1; + suppress_warning (newval); rhs = build4 (TARGET_EXPR, nonatomic_lhs_type, newval, func_call, NULL_TREE, NULL_TREE); SET_EXPR_LOCATION (rhs, loc); @@ -4287,12 +4284,12 @@ cas_loop: old = create_tmp_var_raw (nonatomic_lhs_type); old_addr = build_unary_op (loc, ADDR_EXPR, old, false); TREE_ADDRESSABLE (old) = 1; - TREE_NO_WARNING (old) = 1; + suppress_warning (old); newval = create_tmp_var_raw (nonatomic_lhs_type); newval_addr = build_unary_op (loc, ADDR_EXPR, newval, false); TREE_ADDRESSABLE (newval) = 1; - TREE_NO_WARNING (newval) = 1; + suppress_warning (newval); loop_decl = create_artificial_label (loc); loop_label = build1 (LABEL_EXPR, void_type_node, loop_decl); @@ -4781,8 +4778,6 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, else val = build2 (code, TREE_TYPE (arg), arg, inc); TREE_SIDE_EFFECTS (val) = 1; - if (TREE_CODE (val) != code) - TREE_NO_WARNING (val) = 1; ret = val; goto return_build_unary_op; } @@ -6131,6 +6126,7 @@ build_c_cast (location_t loc, tree type, tree expr) return value reflects this. */ if (int_operands && INTEGRAL_TYPE_P (type) + && value != error_mark_node && !EXPR_INT_CONST_OPERANDS (value)) value = note_integer_operands (value); @@ -10961,7 +10957,8 @@ c_finish_return (location_t loc, tree retval, tree origtype) } ret_stmt = build_stmt (loc, RETURN_EXPR, retval); - TREE_NO_WARNING (ret_stmt) |= no_warning; + if (no_warning) + suppress_warning (ret_stmt, OPT_Wreturn_type); return add_stmt (ret_stmt); } @@ -11237,7 +11234,8 @@ emit_side_effect_warnings (location_t loc, tree expr) ; else if (!TREE_SIDE_EFFECTS (expr)) { - if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr)) + if (!VOID_TYPE_P (TREE_TYPE (expr)) + && !warning_suppressed_p (expr, OPT_Wunused_value)) warning_at (loc, OPT_Wunused_value, "statement with no effect"); } else if (TREE_CODE (expr) == COMPOUND_EXPR) @@ -11253,8 +11251,8 @@ emit_side_effect_warnings (location_t loc, tree expr) if (!TREE_SIDE_EFFECTS (r) && !VOID_TYPE_P (TREE_TYPE (r)) && !CONVERT_EXPR_P (r) - && !TREE_NO_WARNING (r) - && !TREE_NO_WARNING (expr)) + && !warning_suppressed_p (r, OPT_Wunused_value) + && !warning_suppressed_p (expr, OPT_Wunused_value)) warning_at (cloc, OPT_Wunused_value, "right-hand operand of comma expression has no effect"); } @@ -11423,7 +11421,7 @@ c_finish_stmt_expr (location_t loc, tree body) last = c_wrap_maybe_const (last, true); /* Do not warn if the return value of a statement expression is unused. */ - TREE_NO_WARNING (last) = 1; + suppress_warning (last, OPT_Wunused); return last; } @@ -15502,7 +15500,7 @@ c_omp_clause_copy_ctor (tree clause, tree dst, tree src) tree tmp = create_tmp_var (nonatomic_type); tree tmp_addr = build_fold_addr_expr (tmp); TREE_ADDRESSABLE (tmp) = 1; - TREE_NO_WARNING (tmp) = 1; + suppress_warning (tmp); tree src_addr = build_fold_addr_expr (src); tree dst_addr = build_fold_addr_expr (dst); tree seq_cst = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST); diff --git a/gcc/calls.c b/gcc/calls.c index 4bf2b5d..27e8c45 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1623,7 +1623,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) if (!fndecl || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) return false; - if (TREE_NO_WARNING (exp) || !warn_stringop_overread) + if (!warn_stringop_overread || warning_suppressed_p (exp, OPT_Wstringop_overread)) return false; /* Avoid clearly invalid calls (more checking done below). */ @@ -1739,7 +1739,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) exp, fndecl, bndrng[0], bndrng[1], maxobjsize); if (warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return warned; } @@ -1916,7 +1916,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) } if (any_arg_warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return any_arg_warned; } @@ -1979,7 +1979,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) /* Set if a warning has been issued for any argument (used to decide whether to emit an informational note at the end). */ - bool any_warned = false; + opt_code opt_warned = N_OPTS; /* A string describing the attributes that the warnings issued by this function apply to. Used to print one informational note per function @@ -2054,7 +2054,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) *sizstr = '\0'; /* Set if a warning has been issued for the current argument. */ - bool arg_warned = false; + opt_code arg_warned = N_OPTS; location_t loc = EXPR_LOCATION (exp); tree ptr = access.second.ptr; if (*sizstr @@ -2067,24 +2067,25 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) const std::string argtypestr = access.second.array_as_string (ptrtype); - arg_warned = warning_at (loc, OPT_Wstringop_overflow_, - "%Kbound argument %i value %s is " - "negative for a variable length array " - "argument %i of type %s", - exp, sizidx + 1, sizstr, - ptridx + 1, argtypestr.c_str ()); + if (warning_at (loc, OPT_Wstringop_overflow_, + "%Kbound argument %i value %s is " + "negative for a variable length array " + "argument %i of type %s", + exp, sizidx + 1, sizstr, + ptridx + 1, argtypestr.c_str ())) + arg_warned = OPT_Wstringop_overflow_; } - else - arg_warned = warning_at (loc, OPT_Wstringop_overflow_, - "%Kargument %i value %s is negative", - exp, sizidx + 1, sizstr); + else if (warning_at (loc, OPT_Wstringop_overflow_, + "%Kargument %i value %s is negative", + exp, sizidx + 1, sizstr)) + arg_warned = OPT_Wstringop_overflow_; - if (arg_warned) + if (arg_warned != N_OPTS) { append_attrname (access, attrstr, sizeof attrstr); /* Remember a warning has been issued and avoid warning again below for the same attribute. */ - any_warned = true; + opt_warned = arg_warned; continue; } } @@ -2122,31 +2123,33 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) const std::string argtypestr = access.second.array_as_string (ptrtype); - arg_warned = warning_at (loc, OPT_Wnonnull, - "%Kargument %i of variable length " - "array %s is null but " - "the corresponding bound argument " - "%i value is %s", - exp, sizidx + 1, argtypestr.c_str (), - ptridx + 1, sizstr); + if (warning_at (loc, OPT_Wnonnull, + "%Kargument %i of variable length " + "array %s is null but " + "the corresponding bound argument " + "%i value is %s", + exp, sizidx + 1, argtypestr.c_str (), + ptridx + 1, sizstr)) + arg_warned = OPT_Wnonnull; } - else - arg_warned = warning_at (loc, OPT_Wnonnull, - "%Kargument %i is null but " - "the corresponding size argument " - "%i value is %s", - exp, ptridx + 1, sizidx + 1, - sizstr); + else if (warning_at (loc, OPT_Wnonnull, + "%Kargument %i is null but " + "the corresponding size argument " + "%i value is %s", + exp, ptridx + 1, sizidx + 1, + sizstr)) + arg_warned = OPT_Wnonnull; } else if (access_size && access.second.static_p) { /* Warn about null pointers for [static N] array arguments but do not warn for ordinary (i.e., nonstatic) arrays. */ - arg_warned = warning_at (loc, OPT_Wnonnull, - "%Kargument %i to %<%T[static %E]%> " - "is null where non-null expected", - exp, ptridx + 1, argtype, - access_size); + if (warning_at (loc, OPT_Wnonnull, + "%Kargument %i to %<%T[static %E]%> " + "is null where non-null expected", + exp, ptridx + 1, argtype, + access_size)) + arg_warned = OPT_Wnonnull; } if (arg_warned) @@ -2154,7 +2157,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) append_attrname (access, attrstr, sizeof attrstr); /* Remember a warning has been issued and avoid warning again below for the same attribute. */ - any_warned = true; + opt_warned = OPT_Wnonnull; continue; } } @@ -2190,17 +2193,17 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) /* Clear the no-warning bit in case it was set by check_access in a prior iteration so that accesses via different arguments are diagnosed. */ - TREE_NO_WARNING (exp) = false; + suppress_warning (exp, OPT_Wstringop_overflow_, false); access_mode mode = data.mode; if (mode == access_deferred) mode = TYPE_READONLY (argtype) ? access_read_only : access_read_write; check_access (exp, access_size, /*maxread=*/ NULL_TREE, srcsize, dstsize, mode, &data); - if (TREE_NO_WARNING (exp)) + if (warning_suppressed_p (exp, OPT_Wstringop_overflow_)) + opt_warned = OPT_Wstringop_overflow_; + if (opt_warned != N_OPTS) { - any_warned = true; - if (access.second.internal_p) inform (loc, "referencing argument %u of type %qT", ptridx + 1, ptrtype); @@ -2222,7 +2225,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) "in a call with type %qT and attribute %qs", fntype, attrstr); } - else if (any_warned) + else if (opt_warned != N_OPTS) { if (fndecl) inform (DECL_SOURCE_LOCATION (fndecl), @@ -2233,7 +2236,8 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) } /* Set the bit in case if was cleared and not set above. */ - TREE_NO_WARNING (exp) = true; + if (opt_warned != N_OPTS) + suppress_warning (exp, opt_warned); } /* Fill in ARGS_SIZE and ARGS array based on the parameters found in diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 6394cfd..3edd53c 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2807,9 +2807,6 @@ expand_call_stmt (gcall *stmt) if (gimple_call_nothrow_p (stmt)) TREE_NOTHROW (exp) = 1; - if (gimple_no_warning_p (stmt)) - TREE_NO_WARNING (exp) = 1; - CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt); CALL_EXPR_MUST_TAIL_CALL (exp) = gimple_call_must_tail_p (stmt); CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt); @@ -2823,6 +2820,9 @@ expand_call_stmt (gcall *stmt) CALL_EXPR_BY_DESCRIPTOR (exp) = gimple_call_by_descriptor_p (stmt); SET_EXPR_LOCATION (exp, gimple_location (stmt)); + /* Must come after copying location. */ + copy_warning (exp, stmt); + /* Ensure RTL is created for debug args. */ if (decl && DECL_HAS_DEBUG_ARGS_P (decl)) { diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 098eb99..55cb034 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1074,7 +1074,7 @@ check_global_declaration (symtab_node *snode) && ! DECL_ARTIFICIAL (decl) && ! TREE_PUBLIC (decl)) { - if (TREE_NO_WARNING (decl)) + if (warning_suppressed_p (decl, OPT_Wunused)) ; else if (snode->referred_to_p (/*include_self=*/false)) pedwarn (input_location, 0, "%q+F used but never defined", decl); diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 2cb939e..e9763eb 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -5161,6 +5161,18 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p) else unpack = gen_sse4_1_sign_extendv2siv2di2; break; + case E_V8QImode: + if (unsigned_p) + unpack = gen_sse4_1_zero_extendv4qiv4hi2; + else + unpack = gen_sse4_1_sign_extendv4qiv4hi2; + break; + case E_V4HImode: + if (unsigned_p) + unpack = gen_sse4_1_zero_extendv2hiv2si2; + else + unpack = gen_sse4_1_sign_extendv2hiv2si2; + break; default: gcc_unreachable (); } @@ -5172,10 +5184,24 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p) } else if (high_p) { - /* Shift higher 8 bytes to lower 8 bytes. */ - tmp = gen_reg_rtx (V1TImode); - emit_insn (gen_sse2_lshrv1ti3 (tmp, gen_lowpart (V1TImode, src), - GEN_INT (64))); + switch (GET_MODE_SIZE (imode)) + { + case 16: + /* Shift higher 8 bytes to lower 8 bytes. */ + tmp = gen_reg_rtx (V1TImode); + emit_insn (gen_sse2_lshrv1ti3 (tmp, gen_lowpart (V1TImode, src), + GEN_INT (64))); + break; + case 8: + /* Shift higher 4 bytes to lower 4 bytes. */ + tmp = gen_reg_rtx (V1DImode); + emit_insn (gen_mmx_lshrv1di3 (tmp, gen_lowpart (V1DImode, src), + GEN_INT (32))); + break; + default: + gcc_unreachable (); + } + tmp = gen_lowpart (imode, tmp); } else @@ -5207,6 +5233,18 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p) else unpack = gen_vec_interleave_lowv4si; break; + case E_V8QImode: + if (high_p) + unpack = gen_mmx_punpckhbw; + else + unpack = gen_mmx_punpcklbw; + break; + case E_V4HImode: + if (high_p) + unpack = gen_mmx_punpckhwd; + else + unpack = gen_mmx_punpcklwd; + break; default: gcc_unreachable (); } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3d5883b..c71c9e6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -20476,15 +20476,6 @@ x86_order_regs_for_local_alloc (void) int pos = 0; int i; - /* When allocano cost of GENERAL_REGS is same as MASK_REGS, allocate - MASK_REGS first since it has already been disparaged. This is for - testcase bitwise_mask_op3.c where the input is allocated as mask - registers, then mask bitwise instructions should be used there. - Refer to pr101142. */ - /* Mask register. */ - for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++) - reg_alloc_order [pos++] = i; - /* First allocate the local general purpose registers. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (GENERAL_REGNO_P (i) && call_used_or_fixed_reg_p (i)) @@ -20511,6 +20502,10 @@ x86_order_regs_for_local_alloc (void) for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++) reg_alloc_order [pos++] = i; + /* Mask register. */ + for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++) + reg_alloc_order [pos++] = i; + /* x87 registers. */ if (TARGET_SSE_MATH) for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9043be3..9b619e2 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1000,6 +1000,9 @@ (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")]) +;; Instruction suffix for SSE sign and zero extensions. +(define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")]) + ;; Used in signed and unsigned fix. (define_code_iterator any_fix [fix unsigned_fix]) (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")]) diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 7a827dc..e887f034 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -2639,6 +2639,78 @@ (set_attr "type" "mmxcvt,sselog,sselog") (set_attr "mode" "DI,TI,TI")]) +(define_insn "sse4_1_<code>v4qiv4hi2" + [(set (match_operand:V4HI 0 "register_operand" "=Yr,*x,Yw") + (any_extend:V4HI + (vec_select:V4QI + (match_operand:V8QI 1 "register_operand" "Yr,*x,Yw") + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3)]))))] + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" + "%vpmov<extsuffix>bw\t{%1, %0|%0, %1}" + [(set_attr "isa" "noavx,noavx,avx") + (set_attr "type" "ssemov") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "orig,orig,maybe_evex") + (set_attr "mode" "TI")]) + +(define_insn "sse4_1_<code>v2hiv2si2" + [(set (match_operand:V2SI 0 "register_operand" "=Yr,*x,v") + (any_extend:V2SI + (vec_select:V2HI + (match_operand:V4HI 1 "register_operand" "Yr,*x,v") + (parallel [(const_int 0) (const_int 1)]))))] + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" + "%vpmov<extsuffix>wd\t{%1, %0|%0, %1}" + [(set_attr "isa" "noavx,noavx,avx") + (set_attr "type" "ssemov") + (set_attr "prefix_extra" "1") + (set_attr "prefix" "orig,orig,maybe_evex") + (set_attr "mode" "TI")]) + +;; Pack/unpack vector modes +(define_mode_attr mmxpackmode + [(V4HI "V8QI") (V2SI "V4HI")]) + +(define_expand "vec_pack_trunc_<mode>" + [(match_operand:<mmxpackmode> 0 "register_operand") + (match_operand:MMXMODE24 1 "register_operand") + (match_operand:MMXMODE24 2 "register_operand")] + "TARGET_MMX_WITH_SSE" +{ + rtx op1 = gen_lowpart (<mmxpackmode>mode, operands[1]); + rtx op2 = gen_lowpart (<mmxpackmode>mode, operands[2]); + ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0); + DONE; +}) + +(define_mode_attr mmxunpackmode + [(V8QI "V4HI") (V4HI "V2SI")]) + +(define_expand "vec_unpacks_lo_<mode>" + [(match_operand:<mmxunpackmode> 0 "register_operand") + (match_operand:MMXMODE12 1 "register_operand")] + "TARGET_MMX_WITH_SSE" + "ix86_expand_sse_unpack (operands[0], operands[1], false, false); DONE;") + +(define_expand "vec_unpacks_hi_<mode>" + [(match_operand:<mmxunpackmode> 0 "register_operand") + (match_operand:MMXMODE12 1 "register_operand")] + "TARGET_MMX_WITH_SSE" + "ix86_expand_sse_unpack (operands[0], operands[1], false, true); DONE;") + +(define_expand "vec_unpacku_lo_<mode>" + [(match_operand:<mmxunpackmode> 0 "register_operand") + (match_operand:MMXMODE12 1 "register_operand")] + "TARGET_MMX_WITH_SSE" + "ix86_expand_sse_unpack (operands[0], operands[1], true, false); DONE;") + +(define_expand "vec_unpacku_hi_<mode>" + [(match_operand:<mmxunpackmode> 0 "register_operand") + (match_operand:MMXMODE12 1 "register_operand")] + "TARGET_MMX_WITH_SSE" + "ix86_expand_sse_unpack (operands[0], operands[1], true, true); DONE;") + (define_insn "*mmx_pinsrd" [(set (match_operand:V2SI 0 "register_operand" "=x,Yv") (vec_merge:V2SI diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 2d29877..e4f01e6 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -976,9 +976,6 @@ [(V8SI "si") (V8SF "ps") (V4DF "pd") (V16SI "si") (V16SF "ps") (V8DF "pd")]) -;; Instruction suffix for sign and zero extensions. -(define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")]) - ;; i128 for integer vectors and TARGET_AVX2, f128 otherwise. ;; i64x4 or f64x4 for 512bit modes. (define_mode_attr i128 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 368ef75..770d327 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,33 @@ +2021-06-24 Patrick Palka <ppalka@redhat.com> + + PR c++/98832 + * pt.c (maybe_aggr_guide): Handle alias templates appropriately. + +2021-06-24 Patrick Palka <ppalka@redhat.com> + + PR c++/101182 + * constraint.cc (evaluate_requires_expr): Adjust function comment. + * cp-gimplify.c (cp_genericize_r) <case REQUIRES_EXPR>: Move to ... + (cp_fold) <case REQUIRES_EXPR>: ... here. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + * parser.c (cp_omp_split_clauses): Pass C_ORT_OMP_TARGET instead of + C_ORT_OMP for clauses on target construct. + (OMP_TARGET_CLAUSE_MASK): Add in_reduction clause. + (cp_parser_omp_target): For non-combined target add + map (always, tofrom:) clauses for OMP_CLAUSE_IN_REDUCTION. Pass + C_ORT_OMP_TARGET to finish_omp_clauses. + * semantics.c (handle_omp_array_sections_1): Adjust ort handling + for addition of C_ORT_OMP_TARGET and simplify, mapping clauses are + never present on C_ORT_*DECLARE_SIMD. + (handle_omp_array_sections): Likewise. + (finish_omp_clauses): Likewise. Handle OMP_CLAUSE_IN_REDUCTION + on C_ORT_OMP_TARGET, set OMP_CLAUSE_MAP_IN_REDUCTION on + corresponding map clauses. + * pt.c (tsubst_expr): Pass C_ORT_OMP_TARGET instead of C_ORT_OMP for + clauses on target construct. + 2021-06-23 Patrick Palka <ppalka@redhat.com> PR c++/101174 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index aafc7ac..e4df72e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9499,7 +9499,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { /* Avoid copying empty classes. */ val = build2 (COMPOUND_EXPR, type, arg, to); - TREE_NO_WARNING (val) = 1; + suppress_warning (val, OPT_Wunused); } else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base))) { @@ -9530,7 +9530,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) build2 (MEM_REF, array_type, arg0, alias_set), build2 (MEM_REF, array_type, arg, alias_set)); val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to); - TREE_NO_WARNING (val) = 1; + suppress_warning (val, OPT_Wunused); } cp_warn_deprecated_use (fn, complain); @@ -9604,7 +9604,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { tree c = extract_call_expr (call); if (TREE_CODE (c) == CALL_EXPR) - TREE_NO_WARNING (c) = 1; + suppress_warning (c /* Suppress all warnings. */); } if (TREE_CODE (fn) == ADDR_EXPR) { @@ -12554,11 +12554,11 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups, TREE_ADDRESSABLE (var) = 1; if (TREE_CODE (decl) == FIELD_DECL - && extra_warnings && !TREE_NO_WARNING (decl)) + && extra_warnings && !warning_suppressed_p (decl)) { warning (OPT_Wextra, "a temporary bound to %qD only persists " "until the constructor exits", decl); - TREE_NO_WARNING (decl) = true; + suppress_warning (decl); } /* Recursively extend temps in this initializer. */ diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b53a4db..c89ffad 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6704,7 +6704,7 @@ layout_class_type (tree t, tree *virtuals_p) laying out an Objective-C class. The ObjC ABI differs from the C++ ABI, and so we do not want a warning here. */ - && !TREE_NO_WARNING (field) + && !warning_suppressed_p (field, OPT_Wabi) && !last_field_was_bitfield && !integer_zerop (size_binop (TRUNC_MOD_EXPR, DECL_FIELD_BIT_OFFSET (field), diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 74b16d2..6df3ca6 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3290,14 +3290,14 @@ constraint_satisfaction_value (tree t, tree args, sat_info info) else r = satisfy_nondeclaration_constraints (t, args, info); if (r == error_mark_node && info.quiet () - && !(DECL_P (t) && TREE_NO_WARNING (t))) + && !(DECL_P (t) && warning_suppressed_p (t))) { /* Replay the error noisily. */ sat_info noisy (tf_warning_or_error, info.in_decl); constraint_satisfaction_value (t, args, noisy); if (DECL_P (t) && !args) /* Avoid giving these errors again. */ - TREE_NO_WARNING (t) = true; + suppress_warning (t); } return r; } @@ -3340,7 +3340,7 @@ evaluate_concept_check (tree check) } /* Evaluate the requires-expression T, returning either boolean_true_node - or boolean_false_node. This is used during gimplification and constexpr + or boolean_false_node. This is used during folding and constexpr evaluation. */ tree diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 1bf1931..a1b0b31 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1078,7 +1078,7 @@ finish_co_await_expr (location_t kw, tree expr) is declared to return non-void (most likely). This is correct - we synthesize the return for the ramp in the compiler. So suppress any extraneous warnings during substitution. */ - TREE_NO_WARNING (current_function_decl) = true; + suppress_warning (current_function_decl, OPT_Wreturn_type); /* If we don't know the promise type, we can't proceed, build the co_await with the expression unchanged. */ @@ -1154,7 +1154,7 @@ finish_co_yield_expr (location_t kw, tree expr) is declared to return non-void (most likely). This is correct - we synthesize the return for the ramp in the compiler. So suppress any extraneous warnings during substitution. */ - TREE_NO_WARNING (current_function_decl) = true; + suppress_warning (current_function_decl, OPT_Wreturn_type); /* If we don't know the promise type, we can't proceed, build the co_await with the expression unchanged. */ @@ -1235,7 +1235,7 @@ finish_co_return_stmt (location_t kw, tree expr) is declared to return non-void (most likely). This is correct - we synthesize the return for the ramp in the compiler. So suppress any extraneous warnings during substitution. */ - TREE_NO_WARNING (current_function_decl) = true; + suppress_warning (current_function_decl, OPT_Wreturn_type); if (processing_template_decl && check_for_bare_parameter_packs (expr)) @@ -1259,7 +1259,7 @@ finish_co_return_stmt (location_t kw, tree expr) /* Suppress -Wreturn-type for co_return, we need to check indirectly whether the promise type has a suitable return_void/return_value. */ - TREE_NO_WARNING (current_function_decl) = true; + suppress_warning (current_function_decl, OPT_Wreturn_type); if (!processing_template_decl && warn_sequence_point) verify_sequence_points (expr); @@ -2458,7 +2458,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* done. */ r = build_stmt (loc, RETURN_EXPR, NULL); - TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */ + suppress_warning (r); /* We don't want a warning about this. */ r = maybe_cleanup_point_expr_void (r); add_stmt (r); @@ -2467,7 +2467,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, add_stmt (r); r = build_stmt (loc, RETURN_EXPR, NULL); - TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */ + suppress_warning (r); /* We don't want a warning about this. */ r = maybe_cleanup_point_expr_void (r); add_stmt (r); @@ -4142,7 +4142,7 @@ coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig, finish_if_stmt_cond (not_iarc, not_iarc_if); /* If the initial await resume called value is false, rethrow... */ tree rethrow = build_throw (fn_start, NULL_TREE); - TREE_NO_WARNING (rethrow) = true; + suppress_warning (rethrow); finish_expr_stmt (rethrow); finish_then_clause (not_iarc_if); tree iarc_scope = IF_SCOPE (not_iarc_if); @@ -4243,7 +4243,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) /* For early errors, we do not want a diagnostic about the missing ramp return value, since the user cannot fix this - a 'return' is not allowed in a coroutine. */ - TREE_NO_WARNING (orig) = true; + suppress_warning (orig, OPT_Wreturn_type); /* Discard the body, we can't process it further. */ pop_stmt_list (DECL_SAVED_TREE (orig)); DECL_SAVED_TREE (orig) = push_stmt_list (); @@ -4269,7 +4269,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) DECL_SAVED_TREE (orig) = push_stmt_list (); append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig)); /* Suppress warnings about the missing return value. */ - TREE_NO_WARNING (orig) = true; + suppress_warning (orig, OPT_Wreturn_type); return false; } @@ -4948,7 +4948,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body); DECL_SAVED_TREE (orig) = newbody; /* Suppress warnings about the missing return value. */ - TREE_NO_WARNING (orig) = true; + suppress_warning (orig, OPT_Wreturn_type); return false; } @@ -5159,7 +5159,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) promise_type, fn_start); finish_expr_stmt (del_coro_fr); tree rethrow = build_throw (fn_start, NULL_TREE); - TREE_NO_WARNING (rethrow) = true; + suppress_warning (rethrow); finish_expr_stmt (rethrow); finish_handler (handler); TRY_HANDLERS (ramp_cleanup) = pop_stmt_list (TRY_HANDLERS (ramp_cleanup)); diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 96d91b6..00b7772 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -101,8 +101,8 @@ genericize_eh_spec_block (tree *stmt_p) tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ()); *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure); - TREE_NO_WARNING (*stmt_p) = true; - TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true; + suppress_warning (*stmt_p); + suppress_warning (TREE_OPERAND (*stmt_p, 1)); } /* Return the first non-compound statement in STMT. */ @@ -220,7 +220,7 @@ gimplify_expr_stmt (tree *stmt_p) { if (!IS_EMPTY_STMT (stmt) && !VOID_TYPE_P (TREE_TYPE (stmt)) - && !TREE_NO_WARNING (stmt)) + && !warning_suppressed_p (stmt, OPT_Wunused_value)) warning (OPT_Wunused_value, "statement with no effect"); } else @@ -1328,7 +1328,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) case THROW_EXPR: { location_t loc = location_of (stmt); - if (TREE_NO_WARNING (stmt)) + if (warning_suppressed_p (stmt /* What warning? */)) /* Never mind. */; else if (wtd->try_block) { @@ -1465,12 +1465,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) TARGET_EXPR_NO_ELIDE (stmt) = 1; break; - case REQUIRES_EXPR: - /* Emit the value of the requires-expression. */ - *stmt_p = evaluate_requires_expr (stmt); - *walk_subtrees = 0; - break; - case TEMPLATE_ID_EXPR: gcc_assert (concept_check_p (stmt)); /* Emit the value of the concept check. */ @@ -2449,8 +2443,9 @@ cp_fold (tree x) ; else if (COMPARISON_CLASS_P (x)) { - if (TREE_NO_WARNING (org_x) && warn_nonnull_compare) - TREE_NO_WARNING (x) = 1; + if (warn_nonnull_compare + && warning_suppressed_p (org_x, OPT_Wnonnull_compare)) + suppress_warning (x, OPT_Wnonnull_compare); } /* Otherwise give up on optimizing these, let GIMPLE folders optimize those later on. */ @@ -2458,8 +2453,9 @@ cp_fold (tree x) || op1 != TREE_OPERAND (org_x, 1)) { x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1); - if (TREE_NO_WARNING (org_x) && warn_nonnull_compare) - TREE_NO_WARNING (x) = 1; + if (warn_nonnull_compare + && warning_suppressed_p (org_x, OPT_Wnonnull_compare)) + suppress_warning (x, OPT_Wnonnull_compare); } else x = org_x; @@ -2708,6 +2704,10 @@ cp_fold (tree x) x = r; break; + case REQUIRES_EXPR: + x = evaluate_requires_expr (x); + break; + default: return org_x; } @@ -2715,7 +2715,7 @@ cp_fold (tree x) if (EXPR_P (x) && TREE_CODE (x) == code) { TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x); - TREE_NO_WARNING (x) = TREE_NO_WARNING (org_x); + copy_warning (x, org_x); } if (!c.evaluation_restricted_p ()) diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c index 3dabb6a..7854594 100644 --- a/gcc/cp/cp-ubsan.c +++ b/gcc/cp/cp-ubsan.c @@ -81,7 +81,7 @@ cp_ubsan_instrument_vptr (location_t loc, tree op, tree type, bool is_addr, build_zero_cst (TREE_TYPE (op))); /* This is a compiler generated comparison, don't emit e.g. -Wnonnull-compare warning for it. */ - TREE_NO_WARNING (cond) = 1; + suppress_warning (cond, OPT_Wnonnull_compare); vptr = build3_loc (loc, COND_EXPR, uint64_type_node, cond, vptr, build_int_cst (uint64_type_node, 0)); } diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 330d658..d035e61 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -605,8 +605,6 @@ ignore_overflows (tree expr, tree orig) tree cp_fold_convert (tree type, tree expr) { - bool nowarn = TREE_NO_WARNING (expr); - tree conv; if (TREE_TYPE (expr) == type) conv = expr; @@ -630,8 +628,8 @@ cp_fold_convert (tree type, tree expr) conv = ignore_overflows (conv, expr); } - if (nowarn && TREE_CODE (expr) == TREE_CODE (conv)) - TREE_NO_WARNING (conv) = nowarn; + if (TREE_CODE (expr) == TREE_CODE (conv)) + copy_warning (conv, expr); return conv; } @@ -1208,7 +1206,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) /* The second part of a compound expr contains the value. */ tree op1 = TREE_OPERAND (expr,1); tree new_op1; - if (implicit != ICV_CAST && !TREE_NO_WARNING (expr)) + if (implicit != ICV_CAST && !warning_suppressed_p (expr /* What warning? */)) new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain); else new_op1 = convert_to_void (op1, ICV_CAST, complain); @@ -1394,7 +1392,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) if (warn_unused_value && implicit != ICV_CAST && (complain & tf_warning) - && !TREE_NO_WARNING (expr) + && !warning_suppressed_p (expr, OPT_Wunused_value) && !is_reference) warning_at (loc, OPT_Wunused_value, "value computed is not used"); expr = TREE_OPERAND (expr, 0); @@ -1578,7 +1576,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { if (implicit != ICV_CAST && warn_unused_value - && !TREE_NO_WARNING (expr) + && !warning_suppressed_p (expr, OPT_Wunused_value) && !processing_template_decl && !cp_unevaluated_operand && (complain & tf_warning)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 66bcc4b..fa6af6f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -850,7 +850,7 @@ wrapup_namespace_globals () && !TREE_PUBLIC (decl) && !DECL_ARTIFICIAL (decl) && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl) - && !TREE_NO_WARNING (decl)) + && !warning_suppressed_p (decl, OPT_Wunused_function)) warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wunused_function, "%qF declared %<static%> but never defined", decl); @@ -13906,10 +13906,7 @@ grokdeclarator (const cp_declarator *declarator, decl = build_decl (id_loc, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; if (bitfield && !unqualified_id) - { - TREE_NO_WARNING (decl) = 1; - DECL_PADDING_P (decl) = 1; - } + DECL_PADDING_P (decl) = 1; if (storage_class == sc_mutable) { @@ -17495,7 +17492,7 @@ finish_function (bool inline_p) /* Don't complain if we are declared noreturn. */ && !TREE_THIS_VOLATILE (fndecl) && !DECL_NAME (DECL_RESULT (fndecl)) - && !TREE_NO_WARNING (fndecl) + && !warning_suppressed_p (fndecl, OPT_Wreturn_type) /* Structor return values (if any) are set by the compiler. */ && !DECL_CONSTRUCTOR_P (fndecl) && !DECL_DESTRUCTOR_P (fndecl) @@ -17523,7 +17520,7 @@ finish_function (bool inline_p) else if (warning_at (&richloc, OPT_Wreturn_type, "no return statement in function returning " "non-void")) - TREE_NO_WARNING (fndecl) = 1; + suppress_warning (fndecl, OPT_Wreturn_type); } /* Lambda closure members are implicitly constexpr if possible. */ @@ -17597,7 +17594,7 @@ finish_function (bool inline_p) && !DECL_READ_P (decl) && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl) - && !TREE_NO_WARNING (decl) + && !warning_suppressed_p (decl,OPT_Wunused_but_set_parameter) && !DECL_IN_SYSTEM_HEADER (decl) && TREE_TYPE (decl) != error_mark_node && !TYPE_REF_P (TREE_TYPE (decl)) @@ -18088,7 +18085,7 @@ require_deduced_type (tree decl, tsubst_flags_t complain) { if (undeduced_auto_decl (decl)) { - if (TREE_NO_WARNING (decl) && seen_error ()) + if (warning_suppressed_p (decl) && seen_error ()) /* We probably already complained about deduction failure. */; else if (complain & tf_error) error ("use of %qD before deduction of %<auto%>", decl); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index e46fded..090a83b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4529,7 +4529,7 @@ no_linkage_error (tree decl) || (errorcount + sorrycount > 0 && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) - && TREE_NO_WARNING (decl)))) + && warning_suppressed_p (decl /* What warning? */)))) /* In C++11 it's ok if the decl is defined. */ return; @@ -5204,7 +5204,7 @@ c_parse_final_cleanups (void) && warning_at (DECL_SOURCE_LOCATION (decl), 0, "inline function %qD used but never defined", decl)) /* Avoid a duplicate warning from check_global_declaration. */ - TREE_NO_WARNING (decl) = 1; + suppress_warning (decl, OPT_Wunused); } /* So must decls that use a type with no linkage. */ diff --git a/gcc/cp/except.c b/gcc/cp/except.c index cbafc09..a8cea53 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -466,7 +466,8 @@ expand_end_catch_block (void) || DECL_DESTRUCTOR_P (current_function_decl))) { tree rethrow = build_throw (input_location, NULL_TREE); - TREE_NO_WARNING (rethrow) = true; + /* Disable all warnings for the generated rethrow statement. */ + suppress_warning (rethrow); finish_expr_stmt (rethrow); } } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 4bd942f..88f6f90 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3536,11 +3536,11 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, the arguments to the constructor call. */ { /* CLEANUP is compiler-generated, so no diagnostics. */ - TREE_NO_WARNING (cleanup) = true; + suppress_warning (cleanup); init_expr = build2 (TRY_CATCH_EXPR, void_type_node, init_expr, cleanup); /* Likewise, this try-catch is compiler-generated. */ - TREE_NO_WARNING (init_expr) = true; + suppress_warning (init_expr); } else /* Ack! First we allocate the memory. Then we set our sentry @@ -3562,7 +3562,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, sentry = TARGET_EXPR_SLOT (begin); /* CLEANUP is compiler-generated, so no diagnostics. */ - TREE_NO_WARNING (cleanup) = true; + suppress_warning (cleanup); TARGET_EXPR_CLEANUP (begin) = build3 (COND_EXPR, void_type_node, sentry, @@ -3576,7 +3576,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, build2 (COMPOUND_EXPR, void_type_node, init_expr, end)); /* Likewise, this is compiler-generated. */ - TREE_NO_WARNING (init_expr) = true; + suppress_warning (init_expr); } } } @@ -3823,7 +3823,7 @@ build_new (location_t loc, vec<tree, va_gc> **placement, tree type, /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */ rval = build1_loc (loc, NOP_EXPR, TREE_TYPE (rval), rval); - TREE_NO_WARNING (rval) = 1; + suppress_warning (rval, OPT_Wunused_value); return rval; } @@ -3995,7 +3995,7 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type, fold_convert (TREE_TYPE (base), nullptr_node)); /* This is a compiler generated comparison, don't emit e.g. -Wnonnull-compare warning for it. */ - TREE_NO_WARNING (cond) = 1; + suppress_warning (cond, OPT_Wnonnull_compare); body = build3_loc (loc, COND_EXPR, void_type_node, cond, body, integer_zero_node); COND_EXPR_IS_VEC_DELETE (body) = true; @@ -4665,7 +4665,7 @@ build_vec_init (tree base, tree maxindex, tree init, atype = build_pointer_type (atype); stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); stmt_expr = cp_build_fold_indirect_ref (stmt_expr); - TREE_NO_WARNING (stmt_expr) = 1; + suppress_warning (stmt_expr /* What warning? */); } return stmt_expr; @@ -4935,7 +4935,7 @@ build_delete (location_t loc, tree otype, tree addr, /* This is a compiler generated comparison, don't emit e.g. -Wnonnull-compare warning for it. */ else if (TREE_CODE (ifexp) == NE_EXPR) - TREE_NO_WARNING (ifexp) = 1; + suppress_warning (ifexp, OPT_Wnonnull_compare); if (!integer_nonzerop (ifexp)) expr = build3 (COND_EXPR, void_type_node, ifexp, expr, void_node); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index dd74523..f268aab 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -3284,7 +3284,7 @@ defaultable_fn_check (tree fn) /* Avoid do_warn_unused_parameter warnings. */ for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p)) if (DECL_NAME (p)) - TREE_NO_WARNING (p) = 1; + suppress_warning (p, OPT_Wunused_parameter); if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) /* Defer checking. */; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b7a4298..096580e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1,3 +1,4 @@ + /* -*- C++ -*- Parser. Copyright (C) 2000-2021 Free Software Foundation, Inc. Written by Mark Mitchell <mark@codesourcery.com>. @@ -5322,7 +5323,7 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1) /* The operands of a fold-expression are cast-expressions, so binary or conditional expressions are not allowed. We check this here to avoid tentative parsing. */ - if (EXPR_P (expr1) && TREE_NO_WARNING (expr1)) + if (EXPR_P (expr1) && warning_suppressed_p (expr1, OPT_Wparentheses)) /* OK, the expression was parenthesized. */; else if (is_binary_op (TREE_CODE (expr1))) error_at (location_of (expr1), @@ -5604,7 +5605,10 @@ cp_parser_primary_expression (cp_parser *parser, /* Consume the `)'. */ token = cp_lexer_peek_token (parser->lexer); location_t close_paren_loc = token->location; + bool no_wparens = warning_suppressed_p (expr, OPT_Wparentheses); expr.set_range (open_paren_loc, close_paren_loc); + if (no_wparens) + suppress_warning (expr, OPT_Wparentheses); if (!parens.require_close (parser) && !cp_parser_uncommitted_to_tentative_parse_p (parser)) cp_parser_skip_to_end_of_statement (parser); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1af8120..e5a2a2c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10954,9 +10954,9 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc) constant expressions. */ if (!targs && limit_bad_template_recursion (tldcl)) { - /* Avoid no_linkage_errors and unused function warnings for this - decl. */ - TREE_NO_WARNING (tldcl) = 1; + /* Avoid no_linkage_errors and unused function (and all other) + warnings for this decl. */ + suppress_warning (tldcl); return false; } @@ -17079,7 +17079,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl); tree op2 = tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl); r = build_nt (code, op0, op1, op2); - TREE_NO_WARNING (r) = TREE_NO_WARNING (t); + copy_warning (r, t); return r; } @@ -19172,8 +19172,7 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl) block = finish_omp_structured_block (block); block = maybe_cleanup_point_expr_void (block); add_decl_expr (omp_out); - if (TREE_NO_WARNING (DECL_EXPR_DECL (stmts[0]))) - TREE_NO_WARNING (omp_out) = 1; + copy_warning (omp_out, DECL_EXPR_DECL (stmts[0])); add_decl_expr (omp_in); finish_expr_stmt (block); } @@ -19854,17 +19853,17 @@ tsubst_copy_and_build (tree t, tree r = build_x_binary_op (input_location, TREE_CODE (t), op0, - (TREE_NO_WARNING (TREE_OPERAND (t, 0)) + (warning_suppressed_p (TREE_OPERAND (t, 0)) ? ERROR_MARK : TREE_CODE (TREE_OPERAND (t, 0))), op1, - (TREE_NO_WARNING (TREE_OPERAND (t, 1)) + (warning_suppressed_p (TREE_OPERAND (t, 1)) ? ERROR_MARK : TREE_CODE (TREE_OPERAND (t, 1))), /*overload=*/NULL, complain|decltype_flag); - if (EXPR_P (r) && TREE_NO_WARNING (t)) - TREE_NO_WARNING (r) = TREE_NO_WARNING (t); + if (EXPR_P (r)) + copy_warning (r, t); RETURN (r); } @@ -20000,8 +19999,8 @@ tsubst_copy_and_build (tree t, set and must be copied. In the latter case, build_x_modify_expr sets it and it must not be reset here. */ - if (TREE_NO_WARNING (t)) - TREE_NO_WARNING (r) = TREE_NO_WARNING (t); + if (warning_suppressed_p (t, OPT_Wparentheses)) + suppress_warning (r, OPT_Wparentheses); RETURN (r); } @@ -28886,6 +28885,8 @@ is_spec_or_derived (tree etype, tree tmpl) return !err; } +static tree alias_ctad_tweaks (tree, tree); + /* Return a C++20 aggregate deduction candidate for TYPE initialized from INIT. */ @@ -28898,6 +28899,15 @@ maybe_aggr_guide (tree tmpl, tree init, vec<tree,va_gc> *args) if (init == NULL_TREE) return NULL_TREE; + if (DECL_ALIAS_TEMPLATE_P (tmpl)) + { + tree under = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); + tree tinfo = get_template_info (under); + if (tree guide = maybe_aggr_guide (TI_TEMPLATE (tinfo), init, args)) + return alias_ctad_tweaks (tmpl, guide); + return NULL_TREE; + } + /* We might be creating a guide for a class member template, e.g., template<typename U> struct A { diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 82eaa28..fcb3308 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -536,14 +536,14 @@ build_if_nonnull (tree test, tree result, tsubst_flags_t complain) /* This is a compiler generated comparison, don't emit e.g. -Wnonnull-compare warning for it. */ - TREE_NO_WARNING (cond) = 1; + suppress_warning (cond, OPT_Wnonnull); null_ptr = cp_convert (TREE_TYPE (result), nullptr_node, complain); cond = build3 (COND_EXPR, TREE_TYPE (result), cond, result, null_ptr); /* Likewise, don't emit -Wnonnull for using the result to call a member function. */ - TREE_NO_WARNING (cond) = 1; + suppress_warning (cond, OPT_Wnonnull); return cond; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fbaabf6..b080259 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -835,12 +835,12 @@ maybe_convert_cond (tree cond) cond = convert_from_reference (cond); if (TREE_CODE (cond) == MODIFY_EXPR - && !TREE_NO_WARNING (cond) && warn_parentheses + && !warning_suppressed_p (cond, OPT_Wparentheses) && warning_at (cp_expr_loc_or_input_loc (cond), OPT_Wparentheses, "suggest parentheses around " "assignment used as truth value")) - TREE_NO_WARNING (cond) = 1; + suppress_warning (cond, OPT_Wparentheses); return condition_conversion (cond); } @@ -1197,7 +1197,7 @@ finish_return_stmt (tree expr) { /* Suppress -Wreturn-type for this function. */ if (warn_return_type) - TREE_NO_WARNING (current_function_decl) = true; + suppress_warning (current_function_decl, OPT_Wreturn_type); return error_mark_node; } @@ -1219,7 +1219,8 @@ finish_return_stmt (tree expr) } r = build_stmt (input_location, RETURN_EXPR, expr); - TREE_NO_WARNING (r) |= no_warning; + if (no_warning) + suppress_warning (r, OPT_Wreturn_type); r = maybe_cleanup_point_expr_void (r); r = add_stmt (r); @@ -2105,7 +2106,7 @@ finish_parenthesized_expr (cp_expr expr) { if (EXPR_P (expr)) /* This inhibits warnings in c_common_truthvalue_conversion. */ - TREE_NO_WARNING (expr) = 1; + suppress_warning (expr, OPT_Wparentheses); if (TREE_CODE (expr) == OFFSET_REF || TREE_CODE (expr) == SCOPE_REF) @@ -5979,12 +5980,12 @@ cp_check_omp_declare_reduction (tree udr) { gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR && TREE_CODE (data.stmts[1]) == DECL_EXPR); - if (TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0]))) + if (warning_suppressed_p (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */)) return true; data.combiner_p = true; if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r, &data, NULL)) - TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])) = 1; + suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */); } if (i >= 6) { @@ -5995,7 +5996,7 @@ cp_check_omp_declare_reduction (tree udr) &data, NULL) || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])), cp_check_omp_declare_reduction_r, &data, NULL)) - TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])) = 1; + suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* Wat warning? */); if (i == 7) gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR); } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 297da2b..2a14fa9 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1127,7 +1127,7 @@ build_cplus_array_type (tree elt_type, tree index_type, int dependent) /* Avoid spurious warnings with VLAs (c++/54583). */ if (TYPE_SIZE (t) && EXPR_P (TYPE_SIZE (t))) - TREE_NO_WARNING (TYPE_SIZE (t)) = 1; + suppress_warning (TYPE_SIZE (t), OPT_Wunused); /* Push these needs up to the ARRAY_TYPE so that initialization takes place more easily. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 937581a..a483e1f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3326,10 +3326,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name) member = DECL_CHAIN (member)) if (DECL_NAME (member) == member_name) break; - tree res = build_simple_component_ref (ptrmem, member); - - TREE_NO_WARNING (res) = 1; - return res; + return build_simple_component_ref (ptrmem, member); } /* Given an expression PTR for a pointer, return an expression @@ -3443,7 +3440,7 @@ cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring, if (warn_strict_aliasing > 2 && cp_strict_aliasing_warning (EXPR_LOCATION (ptr), type, TREE_OPERAND (ptr, 0))) - TREE_NO_WARNING (ptr) = 1; + suppress_warning (ptr, OPT_Wstrict_aliasing); } if (VOID_TYPE_P (t)) @@ -4068,7 +4065,7 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params, { tree c = extract_call_expr (ret); if (TREE_CODE (c) == CALL_EXPR) - TREE_NO_WARNING (c) = 1; + suppress_warning (c, OPT_Wnonnull); } if (allocated != NULL) @@ -4450,14 +4447,14 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain) if (!warn_address || (complain & tf_warning) == 0 || c_inhibit_evaluation_warnings != 0 - || TREE_NO_WARNING (op)) + || warning_suppressed_p (op, OPT_Waddress)) return; tree cop = fold_for_warn (op); if (TREE_CODE (cop) == ADDR_EXPR && decl_with_nonnull_addr_p (TREE_OPERAND (cop, 0)) - && !TREE_NO_WARNING (cop)) + && !warning_suppressed_p (cop, OPT_Waddress)) warning_at (location, OPT_Waddress, "the address of %qD will never " "be NULL", TREE_OPERAND (cop, 0)); @@ -4878,7 +4875,7 @@ cp_build_binary_op (const op_location_t &location, else if (TREE_CODE (type0) == ARRAY_TYPE && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) /* Set by finish_parenthesized_expr. */ - && !TREE_NO_WARNING (op1) + && !warning_suppressed_p (op1, OPT_Wsizeof_array_div) && (complain & tf_warning)) maybe_warn_sizeof_array_div (location, first_arg, type0, op1, non_reference (type1)); @@ -5297,7 +5294,7 @@ cp_build_binary_op (const op_location_t &location, pfn0 = cp_fully_fold (pfn0); /* Avoid -Waddress warnings (c++/64877). */ if (TREE_CODE (pfn0) == ADDR_EXPR) - TREE_NO_WARNING (pfn0) = 1; + suppress_warning (pfn0, OPT_Waddress); pfn1 = pfn_from_ptrmemfunc (op1); pfn1 = cp_fully_fold (pfn1); delta0 = delta_from_ptrmemfunc (op0); @@ -7062,7 +7059,7 @@ unary_complex_lvalue (enum tree_code code, tree arg) tf_warning_or_error); arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result); - TREE_NO_WARNING (arg) = 1; + suppress_warning (arg /* What warning? */); return arg; } @@ -8978,7 +8975,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, TREE_SIDE_EFFECTS (result) = 1; if (!plain_assign) - TREE_NO_WARNING (result) = 1; + suppress_warning (result, OPT_Wparentheses); ret: if (preeval) @@ -9022,7 +9019,7 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, { if (rval == error_mark_node) return rval; - TREE_NO_WARNING (rval) = 1; + suppress_warning (rval /* What warning? */); if (processing_template_decl) { if (overload != NULL_TREE) @@ -9629,13 +9626,13 @@ convert_for_assignment (tree type, tree rhs, if (warn_parentheses && TREE_CODE (type) == BOOLEAN_TYPE && TREE_CODE (rhs) == MODIFY_EXPR - && !TREE_NO_WARNING (rhs) + && !warning_suppressed_p (rhs, OPT_Wparentheses) && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE && (complain & tf_warning) && warning_at (rhs_loc, OPT_Wparentheses, "suggest parentheses around assignment used as " "truth value")) - TREE_NO_WARNING (rhs) = 1; + suppress_warning (rhs, OPT_Wparentheses); if (complain & tf_warning) warn_for_address_or_pointer_of_packed_member (type, rhs); diff --git a/gcc/diagnostic-spec.c b/gcc/diagnostic-spec.c new file mode 100644 index 0000000..fbe52c6 --- /dev/null +++ b/gcc/diagnostic-spec.c @@ -0,0 +1,179 @@ +/* Functions to enable and disable individual warnings on an expression + and statement basis. + Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Martin Sebor <msebor@redhat.com> + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC 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 General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "bitmap.h" +#include "tree.h" +#include "cgraph.h" +#include "hash-map.h" +#include "diagnostic-spec.h" +#include "pretty-print.h" +#include "options.h" + +/* Initialize *THIS from warning option OPT. */ + +nowarn_spec_t::nowarn_spec_t (opt_code opt) +{ + /* Create a very simple mapping based on testing and experience. + It should become more refined with time. */ + switch (opt) + { + case no_warning: + m_bits = 0; + break; + + case all_warnings: + m_bits = -1; + break; + + /* Flow-sensitive warnings about pointer problems issued by both + front ends and the middle end. */ + case OPT_Waddress: + case OPT_Wnonnull: + m_bits = NW_NONNULL; + break; + + /* Flow-sensitive warnings about arithmetic overflow issued by both + front ends and the middle end. */ + case OPT_Woverflow: + case OPT_Wshift_count_negative: + case OPT_Wshift_count_overflow: + case OPT_Wstrict_overflow: + m_bits = NW_VFLOW; + break; + + /* Lexical warnings issued by front ends. */ + case OPT_Wabi: + case OPT_Wlogical_op: + case OPT_Wparentheses: + case OPT_Wreturn_type: + case OPT_Wsizeof_array_div: + case OPT_Wstrict_aliasing: + case OPT_Wunused: + case OPT_Wunused_function: + case OPT_Wunused_but_set_variable: + case OPT_Wunused_variable: + case OPT_Wunused_but_set_parameter: + m_bits = NW_LEXICAL; + break; + + /* Access warning group. */ + case OPT_Warray_bounds: + case OPT_Warray_bounds_: + case OPT_Wformat_overflow_: + case OPT_Wformat_truncation_: + case OPT_Wrestrict: + case OPT_Wstrict_aliasing_: + case OPT_Wstringop_overflow_: + case OPT_Wstringop_overread: + case OPT_Wstringop_truncation: + m_bits = NW_ACCESS; + break; + + /* Initialization warning group. */ + case OPT_Winit_self: + case OPT_Wuninitialized: + case OPT_Wmaybe_uninitialized: + m_bits = NW_UNINIT; + break; + + default: + /* A catchall group for everything else. */ + m_bits = NW_OTHER; + } +} + +/* Map from location to its no-warning disposition. */ + +GTY(()) xint_hash_map_t *nowarn_map; + +/* Return the no-warning disposition for location LOC and option OPT + or for all/any otions by default. */ + +bool +warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */) +{ + if (!nowarn_map) + return false; + + if (const nowarn_spec_t* const pspec = nowarn_map->get (loc)) + { + const nowarn_spec_t optspec (opt); + return *pspec & optspec; + } + + return false; +} + + /* Change the supression of warnings for location LOC. + OPT controls which warnings are affected. + The wildcard OPT of -1 controls all warnings. + If SUPP is true (the default), enable the suppression of the warnings. + If SUPP is false, disable the suppression of the warnings. */ + +bool +suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */, + bool supp /* = true */) +{ + const nowarn_spec_t optspec (supp ? opt : opt_code ()); + + if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL) + { + if (supp) + { + *pspec |= optspec; + return true; + } + + *pspec &= optspec; + if (*pspec) + return true; + + nowarn_map->remove (loc); + return false; + } + + if (!supp || opt == no_warning) + return false; + + if (!nowarn_map) + nowarn_map = xint_hash_map_t::create_ggc (32); + + nowarn_map->put (loc, optspec); + return true; +} + +/* Copy the no-warning disposition from one location to another. */ + +void +copy_warning (location_t to, location_t from) +{ + if (!nowarn_map) + return; + + if (nowarn_spec_t *pspec = nowarn_map->get (from)) + nowarn_map->put (to, *pspec); + else + nowarn_map->remove (to); +} diff --git a/gcc/diagnostic-spec.h b/gcc/diagnostic-spec.h new file mode 100644 index 0000000..4e4d260 --- /dev/null +++ b/gcc/diagnostic-spec.h @@ -0,0 +1,141 @@ +/* Language-independent APIs to enable/disable per-location warnings. + + Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Martin Sebor <msebor@redhat.com> + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC 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 General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef DIAGNOSTIC_SPEC_H_INCLUDED +#define DIAGNOSTIC_SPEC_H_INCLUDED + +#include "hash-map.h" + +/* A "bitset" of warning groups. */ + +class nowarn_spec_t +{ +public: + enum + { + /* Middle end warnings about invalid accesses. */ + NW_ACCESS = 1 << 0, + /* Front end/lexical warnings. */ + NW_LEXICAL = 1 << 1, + /* Warnings about null pointers. */ + NW_NONNULL = 1 << 2, + /* Warnings about uninitialized reads. */ + NW_UNINIT = 1 << 3, + /* Warnings about arithmetic overflow. */ + NW_VFLOW = 1 << 4, + /* All other unclassified warnings. */ + NW_OTHER = 1 << 5, + /* All groups of warnings. */ + NW_ALL = (NW_ACCESS | NW_LEXICAL | NW_NONNULL + | NW_UNINIT | NW_VFLOW | NW_OTHER) + }; + + nowarn_spec_t (): m_bits () { } + + nowarn_spec_t (opt_code); + + /* Return the raw bitset. */ + operator unsigned() const + { + return m_bits; + } + + /* Return true if the bitset is clear. */ + bool operator!() const + { + return !m_bits; + } + + /* Return the inverse of the bitset. */ + nowarn_spec_t operator~() const + { + nowarn_spec_t res (*this); + res.m_bits &= ~NW_ALL; + return res; + } + + /* Set *THIS to the bitwise OR of *THIS and RHS. */ + nowarn_spec_t& operator|= (const nowarn_spec_t &rhs) + { + m_bits |= rhs.m_bits; + return *this; + } + + /* Set *THIS to the bitwise AND of *THIS and RHS. */ + nowarn_spec_t& operator&= (const nowarn_spec_t &rhs) + { + m_bits &= rhs.m_bits; + return *this; + } + + /* Set *THIS to the bitwise exclusive OR of *THIS and RHS. */ + nowarn_spec_t& operator^= (const nowarn_spec_t &rhs) + { + m_bits ^= rhs.m_bits; + return *this; + } + +private: + /* Bitset of warning groups. */ + unsigned m_bits; +}; + +/* Return the bitwise OR of LHS and RHS. */ + +inline nowarn_spec_t +operator| (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return nowarn_spec_t (lhs) |= rhs; +} + +/* Return the bitwise AND of LHS and RHS. */ + +inline nowarn_spec_t +operator& (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return nowarn_spec_t (lhs) &= rhs; +} + +/* Return true if LHS is equal RHS. */ + +inline bool +operator== (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return static_cast<unsigned>(lhs) == static_cast<unsigned>(rhs); +} + +/* Return true if LHS is not equal RHS. */ + +inline bool +operator!= (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return !(lhs == rhs); +} + +typedef location_t key_type_t; +typedef int_hash <key_type_t, 0, UINT_MAX> xint_hash_t; +typedef hash_map<xint_hash_t, nowarn_spec_t> xint_hash_map_t; + +/* A mapping from the location of an expression to the warning spec + set for it. */ +extern GTY(()) xint_hash_map_t *nowarn_map; + +#endif // DIAGNOSTIC_SPEC_H_INCLUDED diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0b33ee9..3aafbc9 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -250,7 +250,7 @@ fold_undefer_overflow_warnings (bool issue, const gimple *stmt, int code) if (!issue || warnmsg == NULL) return; - if (gimple_no_warning_p (stmt)) + if (warning_suppressed_p (stmt, OPT_Wstrict_overflow)) return; /* Use the smallest code level when deciding to issue the @@ -4250,8 +4250,7 @@ fold_truth_not_expr (location_t loc, tree arg) tree ret = build2_loc (loc, code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1)); - if (TREE_NO_WARNING (arg)) - TREE_NO_WARNING (ret) = 1; + copy_warning (ret, arg); return ret; } @@ -9346,7 +9345,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) tem = fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 1)); /* First do the assignment, then return converted constant. */ tem = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (tem), op0, tem); - TREE_NO_WARNING (tem) = 1; + suppress_warning (tem /* What warning? */); TREE_USED (tem) = 1; return tem; } @@ -13519,10 +13518,10 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx, TYPE_CACHED_VALUES (tmp) = NULL; } } - else if (TREE_NO_WARNING (expr) && (DECL_P (expr) || EXPR_P (expr))) + else if (warning_suppressed_p (expr) && (DECL_P (expr) || EXPR_P (expr))) { - /* Allow TREE_NO_WARNING to be set. Perhaps we shouldn't allow that - and change builtins.c etc. instead - see PR89543. */ + /* Allow the no-warning bit to be set. Perhaps we shouldn't allow + that and change builtins.c etc. instead - see PR89543. */ size_t sz = tree_size (expr); buf = XALLOCAVAR (union tree_node, sz); memcpy ((char *) buf, expr, sz); diff --git a/gcc/gengtype.c b/gcc/gengtype.c index b94e2f1..c1fa6d3 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -1727,7 +1727,7 @@ open_base_files (void) "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h", "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-general.h", "omp-offload.h", "ipa-modref-tree.h", "ipa-modref.h", "symtab-thunks.h", - "symtab-clones.h", + "symtab-clones.h", "diagnostic-spec.h", NULL }; const char *const *ifp; diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 199d9f5..13f0868 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -175,7 +175,7 @@ bool array_bounds_checker::check_array_ref (location_t location, tree ref, bool ignore_off_by_one) { - if (TREE_NO_WARNING (ref)) + if (warning_suppressed_p (ref, OPT_Warray_bounds)) /* Return true to have the caller prevent warnings for enclosing refs. */ return true; @@ -346,7 +346,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, /* Avoid more warnings when checking more significant subscripts of the same expression. */ ref = TREE_OPERAND (ref, 0); - TREE_NO_WARNING (ref) = 1; + suppress_warning (ref, OPT_Warray_bounds); if (decl) ref = decl; @@ -411,7 +411,7 @@ bool array_bounds_checker::check_mem_ref (location_t location, tree ref, bool ignore_off_by_one) { - if (TREE_NO_WARNING (ref)) + if (warning_suppressed_p (ref, OPT_Warray_bounds)) return false; tree arg = TREE_OPERAND (ref, 0); @@ -770,7 +770,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref, } } - TREE_NO_WARNING (ref) = 1; + suppress_warning (ref, OPT_Warray_bounds); return true; } @@ -787,7 +787,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref, "intermediate array offset %wi is outside array bounds " "of %qT", tmpidx, reftype)) { - TREE_NO_WARNING (ref) = 1; + suppress_warning (ref, OPT_Warray_bounds); return true; } } @@ -818,7 +818,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t) warned = check_mem_ref (location, t, ignore_off_by_one); if (warned) - TREE_NO_WARNING (t) = true; + suppress_warning (t, OPT_Warray_bounds); t = TREE_OPERAND (t, 0); } @@ -826,7 +826,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t) if (TREE_CODE (t) != MEM_REF || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR - || TREE_NO_WARNING (t)) + || warning_suppressed_p (t, OPT_Warray_bounds)) return; tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0); @@ -886,7 +886,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t) if (DECL_P (t)) inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t); - TREE_NO_WARNING (t) = 1; + suppress_warning (t, OPT_Warray_bounds); } } @@ -980,9 +980,10 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree, See pr98266 and pr97595. */ *walk_subtree = false; - /* Propagate the no-warning bit to the outer expression. */ + /* Propagate the no-warning bit to the outer statement to avoid also + issuing -Wstringop-overflow/-overread for the out-of-bounds accesses. */ if (warned) - TREE_NO_WARNING (t) = true; + suppress_warning (wi->stmt, OPT_Warray_bounds); return NULL_TREE; } diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c index c321179..a2563a4 100644 --- a/gcc/gimple-expr.c +++ b/gcc/gimple-expr.c @@ -377,7 +377,6 @@ copy_var_decl (tree var, tree name, tree type) DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var); DECL_IGNORED_P (copy) = DECL_IGNORED_P (var); DECL_CONTEXT (copy) = DECL_CONTEXT (var); - TREE_NO_WARNING (copy) = TREE_NO_WARNING (var); TREE_USED (copy) = 1; DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var); @@ -387,6 +386,7 @@ copy_var_decl (tree var, tree name, tree type) DECL_USER_ALIGN (copy) = 1; } + copy_warning (copy, var); return copy; } diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 1c0e930..6803153 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -2044,7 +2044,7 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, not point to objects and so do not indicate an overlap; such calls could be the result of sanitization and jump threading). */ - if (!integer_zerop (dest) && !gimple_no_warning_p (stmt)) + if (!integer_zerop (dest) && !warning_suppressed_p (stmt, OPT_Wrestrict)) { tree func = gimple_call_fndecl (stmt); @@ -2071,9 +2071,9 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, if (nonstr) { /* Avoid folding calls with unterminated arrays. */ - if (!gimple_no_warning_p (stmt)) + if (!warning_suppressed_p (stmt, OPT_Wstringop_overread)) warn_string_no_nul (loc, NULL_TREE, "strcpy", src, nonstr); - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overread); return false; } @@ -2481,7 +2481,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi) unsigned HOST_WIDE_INT dstsize; - bool nowarn = gimple_no_warning_p (stmt); + bool nowarn = warning_suppressed_p (stmt, OPT_Wstringop_overflow_); if (!nowarn && compute_builtin_object_size (dst, 1, &dstsize)) { @@ -2504,7 +2504,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi) "destination size %wu"), stmt, fndecl, len, dstsize); if (nowarn) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overflow_); } } @@ -2520,7 +2520,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi) if (warning_at (loc, OPT_Wstringop_overflow_, "%G%qD specified bound %E equals source length", stmt, fndecl, len)) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overflow_); } tree fn = builtin_decl_implicit (BUILT_IN_STRCAT); @@ -3105,7 +3105,8 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi, not point to objects and so do not indicate an overlap; such calls could be the result of sanitization and jump threading). */ - if (!integer_zerop (dest) && !gimple_no_warning_p (stmt)) + if (!integer_zerop (dest) + && !warning_suppressed_p (stmt, OPT_Wrestrict)) { tree func = gimple_call_fndecl (stmt); @@ -3288,10 +3289,10 @@ gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi) if (data.decl) { /* Avoid folding calls with unterminated arrays. */ - if (!gimple_no_warning_p (stmt)) + if (!warning_suppressed_p (stmt, OPT_Wstringop_overread)) warn_string_no_nul (loc, NULL_TREE, "stpcpy", src, data.decl, size, exact); - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overread); return false; } @@ -3554,8 +3555,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi) /* Propagate the NO_WARNING bit to avoid issuing the same warning more than once. */ - if (gimple_no_warning_p (stmt)) - gimple_set_no_warning (repl, true); + copy_warning (repl, stmt); gimple_seq_add_stmt_without_update (&stmts, repl); if (tree lhs = gimple_call_lhs (stmt)) @@ -3606,8 +3606,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi) /* Propagate the NO_WARNING bit to avoid issuing the same warning more than once. */ - if (gimple_no_warning_p (stmt)) - gimple_set_no_warning (repl, true); + copy_warning (repl, stmt); gimple_seq_add_stmt_without_update (&stmts, repl); if (tree lhs = gimple_call_lhs (stmt)) @@ -6065,7 +6064,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree)) { bool changed = false; gimple *stmt = gsi_stmt (*gsi); - bool nowarning = gimple_no_warning_p (stmt); + bool nowarning = warning_suppressed_p (stmt, OPT_Wstrict_overflow); unsigned i; fold_defer_overflow_warnings (); diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index a377261..98ecdbb 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -1037,27 +1037,12 @@ ranger_cache::propagate_cache (tree name) new_range.set_undefined (); FOR_EACH_EDGE (e, ei, bb->preds) { + range_on_edge (e_range, e, name); if (DEBUG_RANGE_CACHE) - fprintf (dump_file, " edge %d->%d :", e->src->index, bb->index); - // Get whatever range we can for this edge. - if (!m_gori.outgoing_edge_range_p (e_range, e, name, *this)) { - exit_range (e_range, name, e->src); - if (DEBUG_RANGE_CACHE) - { - fprintf (dump_file, "No outgoing edge range, picked up "); - e_range.dump (dump_file); - fprintf (dump_file, "\n"); - } - } - else - { - if (DEBUG_RANGE_CACHE) - { - fprintf (dump_file, "outgoing range :"); - e_range.dump (dump_file); - fprintf (dump_file, "\n"); - } + fprintf (dump_file, " edge %d->%d :", e->src->index, bb->index); + e_range.dump (dump_file); + fprintf (dump_file, "\n"); } new_range.union_ (e_range); if (new_range.varying_p ()) @@ -1074,7 +1059,11 @@ ranger_cache::propagate_cache (tree name) if (DEBUG_RANGE_CACHE) { if (!ok_p) - fprintf (dump_file, " Cache failure to store value."); + { + fprintf (dump_file, " Cache failure to store value:"); + print_generic_expr (dump_file, name, TDF_SLIM); + fprintf (dump_file, " "); + } else { fprintf (dump_file, " Updating range to "); diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 583348e..1fa4ace 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -617,7 +617,7 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) } } else if (is_a<gcond *> (s)) - postfold_gcond_edges (as_a<gcond *> (s), src); + postfold_gcond_edges (as_a<gcond *> (s), r, src); } else r.set_varying (type); @@ -1247,9 +1247,11 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s, // Register any outgoing edge relations from a conditional branch. void -fold_using_range::postfold_gcond_edges (gcond *s, fur_source &src) +fold_using_range::postfold_gcond_edges (gcond *s, irange& lhs_range, + fur_source &src) { int_range_max r; + int_range<2> e0_range, e1_range; tree name; range_operator *handler; basic_block bb = gimple_bb (s); @@ -1257,10 +1259,27 @@ fold_using_range::postfold_gcond_edges (gcond *s, fur_source &src) edge e0 = EDGE_SUCC (bb, 0); if (!single_pred_p (e0->dest)) e0 = NULL; + else + { + // If this edge is never taken, ignore it. + gcond_edge_range (e0_range, e0); + e0_range.intersect (lhs_range); + if (e0_range.undefined_p ()) + e0 = NULL; + } + edge e1 = EDGE_SUCC (bb, 1); if (!single_pred_p (e1->dest)) e1 = NULL; + else + { + // If this edge is never taken, ignore it. + gcond_edge_range (e1_range, e1); + e1_range.intersect (lhs_range); + if (e1_range.undefined_p ()) + e1 = NULL; + } // At least one edge needs to be single pred. if (!e0 && !e1) @@ -1276,15 +1295,13 @@ fold_using_range::postfold_gcond_edges (gcond *s, fur_source &src) gcc_checking_assert (handler); if (e0) { - gcond_edge_range (r, e0); - relation_kind relation = handler->op1_op2_relation (r); + relation_kind relation = handler->op1_op2_relation (e0_range); if (relation != VREL_NONE) src.register_relation (e0, relation, ssa1, ssa2); } if (e1) { - gcond_edge_range (r, e1); - relation_kind relation = handler->op1_op2_relation (r); + relation_kind relation = handler->op1_op2_relation (e1_range); if (relation != VREL_NONE) src.register_relation (e1, relation, ssa1, ssa2); } diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h index aeb9231..dc1b28f 100644 --- a/gcc/gimple-range-fold.h +++ b/gcc/gimple-range-fold.h @@ -158,6 +158,6 @@ protected: void range_of_ssa_name_with_loop_info (irange &, tree, class loop *, gphi *, fur_source &src); void relation_fold_and_or (irange& lhs_range, gimple *s, fur_source &src); - void postfold_gcond_edges (gcond *s, fur_source &src); + void postfold_gcond_edges (gcond *s, irange &lhs_range, fur_source &src); }; #endif // GCC_GIMPLE_RANGE_FOLD_H diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c index eb23cd4..2dafe84 100644 --- a/gcc/gimple-ssa-isolate-paths.c +++ b/gcc/gimple-ssa-isolate-paths.c @@ -400,6 +400,11 @@ diag_returned_locals (bool maybe, const locmap_t &locmap) gimple *stmt = (*it).first; const args_loc_t &argsloc = (*it).second; location_t stmtloc = gimple_location (stmt); + if (stmtloc == UNKNOWN_LOCATION) + /* When multiple return statements are merged into one it + may not have an associated location. Use the location + of the closing brace instead. */ + stmtloc = cfun->function_end_locus; auto_diagnostic_group d; unsigned nargs = argsloc.locvec.length (); diff --git a/gcc/gimple-ssa-nonnull-compare.c b/gcc/gimple-ssa-nonnull-compare.c index 9d78946..f2757b6 100644 --- a/gcc/gimple-ssa-nonnull-compare.c +++ b/gcc/gimple-ssa-nonnull-compare.c @@ -97,7 +97,7 @@ do_warn_nonnull_compare (function *fun, tree arg) if (op && (POINTER_TYPE_P (TREE_TYPE (arg)) ? integer_zerop (op) : integer_minus_onep (op)) - && !gimple_no_warning_p (stmt)) + && !warning_suppressed_p (stmt, OPT_Wnonnull_compare)) warning_at (loc, OPT_Wnonnull_compare, "%<nonnull%> argument %qD compared to NULL", arg); } diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index fc74466..41e3be6 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -330,7 +330,8 @@ get_format_string (tree format, location_t *ploc) static bool ATTRIBUTE_GCC_DIAG (5, 6) fmtwarn (const substring_loc &fmt_loc, location_t param_loc, - const char *corrected_substring, int opt, const char *gmsgid, ...) + const char *corrected_substring, opt_code opt, + const char *gmsgid, ...) { format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL, corrected_substring); @@ -345,7 +346,8 @@ fmtwarn (const substring_loc &fmt_loc, location_t param_loc, static bool ATTRIBUTE_GCC_DIAG (6, 8) ATTRIBUTE_GCC_DIAG (7, 8) fmtwarn_n (const substring_loc &fmt_loc, location_t param_loc, - const char *corrected_substring, int opt, unsigned HOST_WIDE_INT n, + const char *corrected_substring, opt_code opt, + unsigned HOST_WIDE_INT n, const char *singular_gmsgid, const char *plural_gmsgid, ...) { format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL, @@ -921,7 +923,7 @@ struct call_info } /* Return the warning option corresponding to the called function. */ - int warnopt () const + opt_code warnopt () const { return bounded ? OPT_Wformat_truncation_ : OPT_Wformat_overflow_; } @@ -4680,7 +4682,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry) bool success = compute_format_length (info, &res, ptr_qry.rvals); if (res.warned) - gimple_set_no_warning (info.callstmt, true); + suppress_warning (info.callstmt, info.warnopt ()); /* When optimizing and the printf return value optimization is enabled, attempt to substitute the computed result for the return value of diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 6329479..20959ac 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -4339,10 +4339,12 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) MR_DEPENDENCE_BASE (ops[j]) = base; } if (!integer_zerop (mask)) - /* The load might load some bits (that will be masked off - later on) uninitialized, avoid -W*uninitialized - warnings in that case. */ - TREE_NO_WARNING (ops[j]) = 1; + { + /* The load might load some bits (that will be masked + off later on) uninitialized, avoid -W*uninitialized + warnings in that case. */ + suppress_warning (ops[j], OPT_Wuninitialized); + } stmt = gimple_build_assign (make_ssa_name (dest_type), ops[j]); gimple_set_location (stmt, load_loc); @@ -4524,7 +4526,7 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) provably uninitialized (no stores at all yet or previous store a CLOBBER) we'd optimize away the load and replace it e.g. with 0. */ - TREE_NO_WARNING (load_src) = 1; + suppress_warning (load_src, OPT_Wuninitialized); stmt = gimple_build_assign (tem, load_src); gimple_set_location (stmt, loc); gimple_set_vuse (stmt, new_vuse); diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index c8c9f95..02771e4 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -1431,7 +1431,7 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs) if (!acs.overlap ()) return false; - if (gimple_no_warning_p (call)) + if (warning_suppressed_p (call, OPT_Wrestrict)) return true; /* For convenience. */ @@ -1680,10 +1680,11 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs) be issued, false otherwise. Both initial values of the offsets and their final value computed by the function by incrementing the initial value by the size are - validated. Return true if the offsets are not valid and a diagnostic - has been issued, or would have been issued if DO_WARN had been true. */ + validated. Return the warning number if the offsets are not valid + and a diagnostic has been issued, or would have been issued if + DO_WARN had been true, otherwise an invalid warning number. */ -static bool +static opt_code maybe_diag_access_bounds (gimple *call, tree func, int strict, const builtin_memref &ref, offset_int wroff, bool do_warn) @@ -1695,28 +1696,31 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, since the result is used to make codegen decisions. */ if (ref.sizrange[0] > maxobjsize) { + const opt_code opt = OPT_Wstringop_overflow_; /* Return true without issuing a warning. */ if (!do_warn) - return true; + return opt; - if (ref.ref && TREE_NO_WARNING (ref.ref)) - return false; + if (ref.ref && warning_suppressed_p (ref.ref, OPT_Wstringop_overflow_)) + return no_warning; + bool warned = false; if (warn_stringop_overflow) { if (ref.sizrange[0] == ref.sizrange[1]) - return warning_at (loc, OPT_Wstringop_overflow_, - "%G%qD specified bound %wu " - "exceeds maximum object size %wu", - call, func, ref.sizrange[0].to_uhwi (), - maxobjsize.to_uhwi ()); - - return warning_at (loc, OPT_Wstringop_overflow_, - "%G%qD specified bound between %wu and %wu " - "exceeds maximum object size %wu", - call, func, ref.sizrange[0].to_uhwi (), - ref.sizrange[1].to_uhwi (), - maxobjsize.to_uhwi ()); + warned = warning_at (loc, opt, + "%G%qD specified bound %wu " + "exceeds maximum object size %wu", + call, func, ref.sizrange[0].to_uhwi (), + maxobjsize.to_uhwi ()); + else + warned = warning_at (loc, opt, + "%G%qD specified bound between %wu and %wu " + "exceeds maximum object size %wu", + call, func, ref.sizrange[0].to_uhwi (), + ref.sizrange[1].to_uhwi (), + maxobjsize.to_uhwi ()); + return warned ? opt : no_warning; } } @@ -1729,18 +1733,19 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff }; tree oobref = ref.offset_out_of_bounds (strict, ooboff); if (!oobref) - return false; + return no_warning; + const opt_code opt = OPT_Warray_bounds; /* Return true without issuing a warning. */ if (!do_warn) - return true; + return opt; if (!warn_array_bounds) - return false; + return no_warning; - if (TREE_NO_WARNING (ref.ptr) - || (ref.ref && TREE_NO_WARNING (ref.ref))) - return false; + if (warning_suppressed_p (ref.ptr, opt) + || (ref.ref && warning_suppressed_p (ref.ref, opt))) + return no_warning; char rangestr[2][64]; if (ooboff[0] == ooboff[1] @@ -1770,7 +1775,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE) { auto_diagnostic_group d; - if (warning_at (loc, OPT_Warray_bounds, + if (warning_at (loc, opt, "%G%qD pointer overflow between offset %s " "and size %s accessing array %qD with type %qT", call, func, rangestr[0], rangestr[1], ref.base, type)) @@ -1780,13 +1785,13 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, warned = true; } else - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, "%G%qD pointer overflow between offset %s " "and size %s", call, func, rangestr[0], rangestr[1]); } else - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, "%G%qD pointer overflow between offset %s " "and size %s", call, func, rangestr[0], rangestr[1]); @@ -1802,7 +1807,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, { auto_diagnostic_group d; if ((ref.basesize < maxobjsize - && warning_at (loc, OPT_Warray_bounds, + && warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out of " "the bounds [0, %wu] of object %qD with " @@ -1811,7 +1816,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, "[0, %wu] of object %qD with type %qT"), call, func, rangestr[0], ref.basesize.to_uhwi (), ref.base, TREE_TYPE (ref.base))) - || warning_at (loc, OPT_Warray_bounds, + || warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out of " "the bounds of object %qD with type %qT") @@ -1826,7 +1831,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, } } else if (ref.basesize < maxobjsize) - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out " "of the bounds [0, %wu]") @@ -1834,7 +1839,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, "of the bounds [0, %wu]"), call, func, rangestr[0], ref.basesize.to_uhwi ()); else - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out of bounds") : G_("%G%qD offset %s is out of bounds"), @@ -1848,7 +1853,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, type = TREE_TYPE (type); type = TYPE_MAIN_VARIANT (type); - if (warning_at (loc, OPT_Warray_bounds, + if (warning_at (loc, opt, "%G%qD offset %s from the object at %qE is out " "of the bounds of %qT", call, func, rangestr[0], ref.base, type)) @@ -1866,7 +1871,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, tree refop = TREE_OPERAND (ref.ref, 0); tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref)); - if (warning_at (loc, OPT_Warray_bounds, + if (warning_at (loc, opt, "%G%qD offset %s from the object at %qE is out " "of the bounds of referenced subobject %qD with " "type %qT at offset %wi", @@ -1883,7 +1888,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, } } - return warned; + return warned ? opt : no_warning; } /* Check a CALL statement for restrict-violations and issue warnings @@ -1894,7 +1899,7 @@ check_call (range_query *query, gimple *call) { /* Avoid checking the call if it has already been diagnosed for some reason. */ - if (gimple_no_warning_p (call)) + if (warning_suppressed_p (call, OPT_Wrestrict)) return; tree func = gimple_call_fndecl (call); @@ -1980,11 +1985,10 @@ check_call (range_query *query, gimple *call) || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr)))) return; - if (!check_bounds_or_overlap (query, call, dst, src, dstwr, NULL_TREE)) - return; - + opt_code opt = check_bounds_or_overlap (query, call, dst, src, dstwr, + NULL_TREE); /* Avoid diagnosing the call again. */ - gimple_set_no_warning (call, true); + suppress_warning (call, opt); } } /* anonymous namespace */ @@ -1996,7 +2000,7 @@ check_call (range_query *query, gimple *call) without issue a warning. Return the OPT_Wxxx constant corresponding to the warning if one has been detected and zero otherwise. */ -int +opt_code check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize, tree srcsize, bool bounds_only /* = false */, bool do_warn /* = true */) @@ -2006,7 +2010,7 @@ check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize, bounds_only, do_warn); } -int +opt_code check_bounds_or_overlap (range_query *query, gimple *call, tree dst, tree src, tree dstsize, tree srcsize, bool bounds_only /* = false */, @@ -2032,16 +2036,20 @@ check_bounds_or_overlap (range_query *query, /* Validate offsets to each reference before the access first to make sure they are within the bounds of the destination object if its size is known, or PTRDIFF_MAX otherwise. */ - if (maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn) - || maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn)) + opt_code opt + = maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn); + if (opt == no_warning) + opt = maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn); + + if (opt != no_warning) { if (do_warn) - gimple_set_no_warning (call, true); - return OPT_Warray_bounds; + suppress_warning (call, opt); + return opt; } if (!warn_restrict || bounds_only || !src) - return 0; + return no_warning; if (!bounds_only) { @@ -2051,7 +2059,7 @@ check_bounds_or_overlap (range_query *query, case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMSET: case BUILT_IN_MEMSET_CHK: - return 0; + return no_warning; default: break; } @@ -2064,26 +2072,26 @@ check_bounds_or_overlap (range_query *query, not point to objects and so do not indicate an overlap; such calls could be the result of sanitization and jump threading). */ - if (!integer_zerop (dst) && !gimple_no_warning_p (call)) + if (!integer_zerop (dst) && !warning_suppressed_p (call, OPT_Wrestrict)) { warning_at (loc, OPT_Wrestrict, "%G%qD source argument is the same as destination", call, func); - gimple_set_no_warning (call, true); + suppress_warning (call, OPT_Wrestrict); return OPT_Wrestrict; } - return 0; + return no_warning; } /* Return false when overlap has been detected. */ if (maybe_diag_overlap (loc, call, acs)) { - gimple_set_no_warning (call, true); + suppress_warning (call, OPT_Wrestrict); return OPT_Wrestrict; } - return 0; + return no_warning; } gimple_opt_pass * diff --git a/gcc/gimple-ssa-warn-restrict.h b/gcc/gimple-ssa-warn-restrict.h index ea89ccc..98c0e24 100644 --- a/gcc/gimple-ssa-warn-restrict.h +++ b/gcc/gimple-ssa-warn-restrict.h @@ -20,10 +20,10 @@ #ifndef GIMPLE_SSA_WARN_RESTRICT_H -extern int check_bounds_or_overlap (gimple *, tree, tree, tree, tree, - bool = false, bool = true); -extern int check_bounds_or_overlap (class range_query *, gimple *, - tree, tree, tree, tree, - bool = false, bool = true); +extern opt_code check_bounds_or_overlap (gimple *, tree, tree, tree, tree, + bool = false, bool = true); +extern opt_code check_bounds_or_overlap (class range_query *, gimple *, + tree, tree, tree, tree, + bool = false, bool = true); #endif /* GIMPLE_SSA_WARN_RESTRICT_H */ diff --git a/gcc/gimple.c b/gcc/gimple.c index f1044e9..60a9066 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -399,7 +399,7 @@ gimple_build_call_from_tree (tree t, tree fnptrtype) gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); gimple_call_set_nothrow (call, TREE_NOTHROW (t)); gimple_call_set_by_descriptor (call, CALL_EXPR_BY_DESCRIPTOR (t)); - gimple_set_no_warning (call, TREE_NO_WARNING (t)); + copy_warning (call, t); if (fnptrtype) { diff --git a/gcc/gimple.h b/gcc/gimple.h index e7dc2a4..be1155e 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1635,6 +1635,24 @@ extern bool gimple_inexpensive_call_p (gcall *); extern bool stmt_can_terminate_bb_p (gimple *); extern location_t gimple_or_expr_nonartificial_location (gimple *, tree); +/* Return the disposition for a warning (or all warnings by default) + for a statement. */ +extern bool warning_suppressed_p (const gimple *, opt_code = all_warnings) + ATTRIBUTE_NONNULL (1); +/* Set the disposition for a warning (or all warnings by default) + at a location to enabled by default. */ +extern void suppress_warning (gimple *, opt_code = all_warnings, + bool = true) ATTRIBUTE_NONNULL (1); + +/* Copy the warning disposition mapping from one statement to another. */ +extern void copy_warning (gimple *, const gimple *) + ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); +/* Copy the warning disposition mapping from an expression to a statement. */ +extern void copy_warning (gimple *, const_tree) + ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); +/* Copy the warning disposition mapping from a statement to an expression. */ +extern void copy_warning (tree, const gimple *) + ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); /* Formal (expression) temporary table handling: multiple occurrences of the same scalar expression are evaluated into the same temporary. */ @@ -1855,16 +1873,17 @@ gimple_block (const gimple *g) return LOCATION_BLOCK (g->location); } +/* Forward declare. */ +static inline void gimple_set_location (gimple *, location_t); /* Set BLOCK to be the lexical scope block holding statement G. */ static inline void gimple_set_block (gimple *g, tree block) { - g->location = set_block (g->location, block); + gimple_set_location (g, set_block (g->location, block)); } - /* Return location information for statement G. */ static inline location_t @@ -1887,6 +1906,8 @@ gimple_location_safe (const gimple *g) static inline void gimple_set_location (gimple *g, location_t location) { + /* Copy the no-warning data to the statement location. */ + copy_warning (location, g->location); g->location = location; } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 4be2feb..75a4a9d 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1601,7 +1601,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) { maybe_add_early_return_predict_stmt (pre_p); greturn *ret = gimple_build_return (ret_expr); - gimple_set_no_warning (ret, TREE_NO_WARNING (stmt)); + copy_warning (ret, stmt); gimplify_seq_add_stmt (pre_p, ret); return GS_ALL_DONE; } @@ -1663,7 +1663,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) we can wind up warning about an uninitialized value for this. Due to how this variable is constructed and initialized, this is never true. Give up and never warn. */ - TREE_NO_WARNING (result) = 1; + suppress_warning (result, OPT_Wuninitialized); gimplify_ctxp->return_temp = result; } @@ -1677,7 +1677,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) maybe_add_early_return_predict_stmt (pre_p); ret = gimple_build_return (result); - gimple_set_no_warning (ret, TREE_NO_WARNING (stmt)); + copy_warning (ret, stmt); gimplify_seq_add_stmt (pre_p, ret); return GS_ALL_DONE; @@ -4252,7 +4252,8 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) &arm2); cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, label_false); - gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr))); + gimple_set_location (cond_stmt, EXPR_LOCATION (expr)); + copy_warning (cond_stmt, COND_EXPR_COND (expr)); gimplify_seq_add_stmt (&seq, cond_stmt); gimple_stmt_iterator gsi = gsi_last (seq); maybe_fold_stmt (&gsi); @@ -5682,7 +5683,7 @@ gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p, ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; other = build1 (ocode, TREE_TYPE (rhs), lhs); - TREE_NO_WARNING (other) = 1; + suppress_warning (other); other = get_formal_tmp_var (other, pre_p); realpart = code == REALPART_EXPR ? rhs : other; @@ -5967,7 +5968,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, assign = gimple_build_assign (*to_p, *from_p); gimple_set_location (assign, EXPR_LOCATION (*expr_p)); if (COMPARISON_CLASS_P (*from_p)) - gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p)); + copy_warning (assign, *from_p); } if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) @@ -6729,7 +6730,7 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p, /* Because of this manipulation, and the EH edges that jump threading cannot redirect, the temporary (VAR) will appear to be used uninitialized. Don't warn. */ - TREE_NO_WARNING (var) = 1; + suppress_warning (var, OPT_Wuninitialized); } } else @@ -14624,7 +14625,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure); ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure); - gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p)); + copy_warning (ehf, *expr_p); gimplify_seq_add_stmt (pre_p, ehf); ret = GS_ALL_DONE; break; diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 5009279..9fd1c65 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -3845,7 +3845,7 @@ expand_omp_for_generic (struct omp_region *region, for (i = first_zero_iter1; i < (fd->ordered ? fd->ordered : fd->collapse); i++) if (SSA_VAR_P (counts[i])) - TREE_NO_WARNING (counts[i]) = 1; + suppress_warning (counts[i], OPT_Wuninitialized); gsi_prev (&gsi); e = split_block (entry_bb, gsi_stmt (gsi)); entry_bb = e->dest; @@ -3862,7 +3862,7 @@ expand_omp_for_generic (struct omp_region *region, be executed in that case, so just avoid uninit warnings. */ for (i = first_zero_iter2; i < fd->ordered; i++) if (SSA_VAR_P (counts[i])) - TREE_NO_WARNING (counts[i]) = 1; + suppress_warning (counts[i], OPT_Wuninitialized); if (zero_iter1_bb) make_edge (zero_iter2_bb, entry_bb, EDGE_FALLTHRU); else @@ -7051,7 +7051,7 @@ expand_omp_taskloop_for_outer (struct omp_region *region, be executed in that case, so just avoid uninit warnings. */ for (i = first_zero_iter; i < fd->collapse; i++) if (SSA_VAR_P (counts[i])) - TREE_NO_WARNING (counts[i]) = 1; + suppress_warning (counts[i], OPT_Wuninitialized); gsi_prev (&gsi); edge e = split_block (entry_bb, gsi_stmt (gsi)); entry_bb = e->dest; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 503754b..410a4a6 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -5695,7 +5695,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, able to notice this and not store anything at all, but we're generating code too early. Suppress the warning. */ if (!by_ref) - TREE_NO_WARNING (var) = 1; + suppress_warning (var, OPT_Wuninitialized); break; case OMP_CLAUSE__CONDTEMP_: @@ -6676,7 +6676,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, uid = create_tmp_var (ptr_type_node, "simduid"); /* Don't want uninit warnings on simduid, it is always uninitialized, but we use it not for the value, but for the DECL_UID only. */ - TREE_NO_WARNING (uid) = 1; + suppress_warning (uid, OPT_Wuninitialized); c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_); OMP_CLAUSE__SIMDUID__DECL (c) = uid; OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt); @@ -7104,7 +7104,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p, if (predicate && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE || OMP_CLAUSE_LINEAR_NO_COPYIN (c))) - TREE_NO_WARNING (new_var) = 1; + suppress_warning (new_var, OPT_Wuninitialized); } if (!maybe_simt && simduid && DECL_HAS_VALUE_EXPR_P (new_var)) @@ -7938,7 +7938,7 @@ lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist, if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !by_ref && is_task_ctx (ctx)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); do_in = true; break; @@ -12800,7 +12800,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) { if (is_gimple_reg (var) && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); var = build_fold_addr_expr (var); } else @@ -12824,7 +12824,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) we'll get a warning for the store to avar. Don't warn in that case, the mapping might be implicit. */ - TREE_NO_WARNING (var) = 1; + suppress_warning (var, OPT_Wuninitialized); gimplify_assign (avar, var, &ilist); } avar = build_fold_addr_expr (avar); @@ -12978,7 +12978,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) if (omp_is_reference (var)) t = build_simple_mem_ref (var); else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); if (TREE_CODE (type) != POINTER_TYPE) t = fold_convert (pointer_sized_int_node, t); t = fold_convert (TREE_TYPE (x), t); @@ -12991,7 +12991,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) tree avar = create_tmp_var (TREE_TYPE (var)); mark_addressable (avar); if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); gimplify_assign (avar, var, &ilist); avar = build_fold_addr_expr (avar); gimplify_assign (x, avar, &ilist); diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 1692a09..29ee9e0 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1299,7 +1299,7 @@ operator_minus::wi_fold (irange &r, tree type, } // Check to see if the relation REL between OP1 and OP2 has any effect on the -// LHS of the epxression. If so, apply it to LHS_RANGE. +// LHS of the expression. If so, apply it to LHS_RANGE. bool operator_minus::op1_op2_relation_effect (irange &lhs_range, tree type, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9ad2094..6895330 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,79 @@ +2021-06-24 Andrew MacLeod <amacleod@redhat.com> + + * gcc.dg/tree-ssa/evrp30.c: New. + +2021-06-24 Andrew MacLeod <amacleod@redhat.com> + + * gcc.dg/tree-ssa/pr101189.c: New. + +2021-06-24 Patrick Palka <ppalka@redhat.com> + + PR c++/98832 + * g++.dg/cpp2a/class-deduction-alias9.C: New test. + +2021-06-24 Patrick Palka <ppalka@redhat.com> + + PR c++/101182 + * g++.dg/cpp2a/concepts-requires25.C: New test. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR c/101171 + * gcc.dg/pr101171.c: New test. + +2021-06-24 Uroš Bizjak <ubizjak@gmail.com> + + PR target/89021 + * gcc.dg/vect/vect-nb-iter-ub-3.c (dg-additional-options): + Add --param vect-epilogues-nomask=0. + * gcc.target/i386/pr97249-1.c (foo): Add #pragma GCC unroll + to avoid loop vectorization. + (foo1): Ditto. + (foo2): Ditto. + +2021-06-24 Richard Biener <rguenther@suse.de> + + * gcc.target/i386/vect-addsubv2df.c: New testcase. + * gcc.target/i386/vect-addsubv4sf.c: Likewise. + * gcc.target/i386/vect-addsubv4df.c: Likewise. + * gcc.target/i386/vect-addsubv8sf.c: Likewise. + * gcc.target/i386/vect-addsub-2.c: Likewise. + * gcc.target/i386/vect-addsub-3.c: Likewise. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/101170 + * gcc.dg/pr101170.c: New test. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/101172 + * gcc.dg/pr101172.c: New test. + +2021-06-24 Ilya Leoshkevich <iii@linux.ibm.com> + + * gcc.target/s390/mnop-mcount-m31-mzarch.c: Adapt to the new + prologue size. + * gcc.target/s390/mnop-mcount-m64.c: Likewise. + +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + * c-c++-common/gomp/target-in-reduction-1.c: New test. + * c-c++-common/gomp/clauses-1.c: Add in_reduction clauses on + target or combined target constructs. + +2021-06-24 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101105 + * gcc.dg/torture/pr101105.c: New testcase. + +2021-06-24 liuhongt <hongtao.liu@intel.com> + + PR target/98434 + * gcc.target/i386/pr98434-1.c: New test. + * gcc.target/i386/pr98434-2.c: New test. + * gcc.target/i386/avx512vl-pr95488-1.c: Adjust testcase. + 2021-06-23 Patrick Palka <ppalka@redhat.com> PR c++/101174 diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias9.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias9.C new file mode 100644 index 0000000..5cc7b7c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias9.C @@ -0,0 +1,6 @@ +// PR c++/98832 +// { dg-do compile { target c++20 } } + +template<class T, class U> struct X { U u; }; +template<class T> using Y = X<int, T>; +Y y{0}; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires25.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires25.C new file mode 100644 index 0000000..90cbedb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires25.C @@ -0,0 +1,10 @@ +// PR c++/101182 +// { dg-do compile { target concepts } } + +int a; +void g(bool); + +bool f() { + g(requires { a++; }); + return requires { a++; }; +} diff --git a/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C b/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C index 56a4e74..76a5ec0 100644 --- a/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C +++ b/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C @@ -20,4 +20,5 @@ int __attribute__((stack_protect)) bar() return 0; } -/* { dg-final { scan-assembler-times "stack_chk_fail" 1 } } */ +/* { dg-final { scan-assembler-times "stack_chk_fail" 1 { target { ! mips*-*-* } } } }*/ +/* { dg-final { scan-assembler-times "stack_chk_fail" 2 { target { mips*-*-* } } } }*/ diff --git a/gcc/testsuite/gcc.dg/pr101171.c b/gcc/testsuite/gcc.dg/pr101171.c new file mode 100644 index 0000000..8d2bcab --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101171.c @@ -0,0 +1,13 @@ +/* PR c/101171 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +extern void foo (void); +int x = 0x1234; + +void +bar (void) +{ + if (x != (sizeof ((enum T) 0x1234))) /* { dg-error "conversion to incomplete type" } */ + foo (); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp30.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp30.c new file mode 100644 index 0000000..2c5ff41 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp30.c @@ -0,0 +1,16 @@ +/* Confirm the ranger is picking up a relationship with equivalences. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void foo (); + +void f (unsigned int a, unsigned int b) +{ + if (a == b) + for (unsigned i = 0; i < a; i++) + if (i == b) // Confirm i < a also means i < b. + foo (); /* Unreachable */ +} + +/* { dg-final { scan-tree-dump-times "foo\\(" 0 "evrp"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c new file mode 100644 index 0000000..5730708 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/101189 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +static int a, b; +int main() { + int d = 0, e, f = 5; + if (a) + f = 0; + for (; f < 4; f++) + ; + e = f ^ -f; + e && d; + if (!e) + e || b; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c b/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c index dbf5091..1666526 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-nb-iter-ub-3.c @@ -1,4 +1,4 @@ -/* { dg-additional-options "-fdump-tree-cunroll-details" } */ +/* { dg-additional-options "-fdump-tree-cunroll-details --param vect-epilogues-nomask=0" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.target/i386/bitwise_mask_op-3.c b/gcc/testsuite/gcc.target/i386/bitwise_mask_op-3.c index 4a90786..352c49d 100644 --- a/gcc/testsuite/gcc.target/i386/bitwise_mask_op-3.c +++ b/gcc/testsuite/gcc.target/i386/bitwise_mask_op-3.c @@ -12,7 +12,7 @@ foo_orb (__m512i a, __m512i b) foo = m1 | m2; } -/* { dg-final { scan-assembler-times "korb\[\t \]" "1" } } */ +/* { dg-final { scan-assembler-times "korb\[\t \]" "1" { xfail *-*-* } } } */ void foo_xorb (__m512i a, __m512i b) @@ -22,7 +22,7 @@ foo_xorb (__m512i a, __m512i b) foo = m1 ^ m2; } -/* { dg-final { scan-assembler-times "kxorb\[\t \]" "1" } } */ +/* { dg-final { scan-assembler-times "kxorb\[\t \]" "1" { xfail *-*-* } } } */ void foo_andb (__m512i a, __m512i b) @@ -40,4 +40,4 @@ foo_andnb (__m512i a, __m512i b) foo = m1 & ~m2; } -/* { dg-final { scan-assembler-times "kmovb\[\t \]" "4"} } */ +/* { dg-final { scan-assembler-times "kmovb\[\t \]" "4" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr97249-1.c b/gcc/testsuite/gcc.target/i386/pr97249-1.c index 4478a34..e7d1d74 100644 --- a/gcc/testsuite/gcc.target/i386/pr97249-1.c +++ b/gcc/testsuite/gcc.target/i386/pr97249-1.c @@ -8,23 +8,26 @@ void foo (unsigned char* p1, unsigned char* p2, short* __restrict p3) { - for (int i = 0 ; i != 8; i++) - p3[i] = p1[i] + p2[i]; - return; + /* Avoid loop vectorization. */ +#pragma GCC unroll 8 + for (int i = 0 ; i != 8; i++) + p3[i] = p1[i] + p2[i]; } void foo1 (unsigned short* p1, unsigned short* p2, int* __restrict p3) { - for (int i = 0 ; i != 4; i++) - p3[i] = p1[i] + p2[i]; - return; + /* Avoid loop vectorization. */ +#pragma GCC unroll 4 + for (int i = 0 ; i != 4; i++) + p3[i] = p1[i] + p2[i]; } void foo2 (unsigned int* p1, unsigned int* p2, long long* __restrict p3) { - for (int i = 0 ; i != 2; i++) - p3[i] = (long long)p1[i] + (long long)p2[i]; - return; + /* Avoid loop vectorization. */ +#pragma GCC unroll 2 + for (int i = 0 ; i != 2; i++) + p3[i] = (long long)p1[i] + (long long)p2[i]; } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index f126d2a..c73e1cb 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -9445,7 +9445,7 @@ pass_warn_function_return::execute (function *fun) /* If we see "return;" in some basic block, then we do reach the end without returning a value. */ else if (warn_return_type > 0 - && !TREE_NO_WARNING (fun->decl) + && !warning_suppressed_p (fun->decl, OPT_Wreturn_type) && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl)))) { FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) @@ -9454,14 +9454,14 @@ pass_warn_function_return::execute (function *fun) greturn *return_stmt = dyn_cast <greturn *> (last); if (return_stmt && gimple_return_retval (return_stmt) == NULL - && !gimple_no_warning_p (last)) + && !warning_suppressed_p (last, OPT_Wreturn_type)) { location = gimple_location (last); if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION) location = fun->function_end_locus; if (warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function")) - TREE_NO_WARNING (fun->decl) = 1; + suppress_warning (fun->decl, OPT_Wreturn_type); break; } } @@ -9469,7 +9469,7 @@ pass_warn_function_return::execute (function *fun) into __builtin_unreachable () call with BUILTINS_LOCATION. Recognize those too. */ basic_block bb; - if (!TREE_NO_WARNING (fun->decl)) + if (!warning_suppressed_p (fun->decl, OPT_Wreturn_type)) FOR_EACH_BB_FN (bb, fun) if (EDGE_COUNT (bb->succs) == 0) { @@ -9493,7 +9493,7 @@ pass_warn_function_return::execute (function *fun) location = fun->function_end_locus; if (warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function")) - TREE_NO_WARNING (fun->decl) = 1; + suppress_warning (fun->decl, OPT_Wreturn_type); break; } } diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index d7d9917..a528cdc 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -456,12 +456,12 @@ create_one_component_var (tree type, tree orig, const char *prefix, SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig)); DECL_HAS_DEBUG_EXPR_P (r) = 1; DECL_IGNORED_P (r) = 0; - TREE_NO_WARNING (r) = TREE_NO_WARNING (orig); + copy_warning (r, orig); } else { DECL_IGNORED_P (r) = 1; - TREE_NO_WARNING (r) = 1; + suppress_warning (r); } return r; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index c5f6ba5..9e041ca 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1116,7 +1116,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data) *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); - TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); + copy_warning (*tp, old); if (MR_DEPENDENCE_CLIQUE (old) != 0) { MR_DEPENDENCE_CLIQUE (*tp) @@ -1375,7 +1375,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); - TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); + copy_warning (*tp, old); if (MR_DEPENDENCE_CLIQUE (old) != 0) { MR_DEPENDENCE_CLIQUE (*tp) @@ -3769,7 +3769,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest, /* Do not have the rest of GCC warn about this variable as it should not be visible to the user. */ - TREE_NO_WARNING (var) = 1; + suppress_warning (var /* OPT_Wuninitialized? */); declare_inline_vars (id->block, var); @@ -5027,7 +5027,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, initialized. We do not want to issue a warning about that uninitialized variable. */ if (DECL_P (modify_dest)) - TREE_NO_WARNING (modify_dest) = 1; + suppress_warning (modify_dest, OPT_Wuninitialized); if (gimple_call_return_slot_opt_p (call_stmt)) { diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 41cbca9..9edd922 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -411,8 +411,8 @@ lookup_field_for_decl (struct nesting_info *info, tree decl, DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl); DECL_IGNORED_P (field) = DECL_IGNORED_P (decl); DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (decl); - TREE_NO_WARNING (field) = TREE_NO_WARNING (decl); TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl); + copy_warning (field, decl); /* Declare the transformation and adjust the original DECL. For a variable or for a parameter when not optimizing, we make it point diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 5e86d3f..c05d22f 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2246,12 +2246,12 @@ create_access_replacement (struct access *access, tree reg_type = NULL_TREE) DECL_HAS_DEBUG_EXPR_P (repl) = 1; } if (access->grp_no_warning) - TREE_NO_WARNING (repl) = 1; + suppress_warning (repl /* Be more selective! */); else - TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base); + copy_warning (repl, access->base); } else - TREE_NO_WARNING (repl) = 1; + suppress_warning (repl /* Be more selective! */); if (dump_file) { @@ -3562,7 +3562,7 @@ generate_subtree_copies (struct access *access, tree agg, } else { - TREE_NO_WARNING (repl) = 1; + suppress_warning (repl /* Be more selective! */); if (access->grp_partial_lhs) repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE, !insert_after, diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 3834212..4258541 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -3527,7 +3527,7 @@ pass_post_ipa_warn::execute (function *fun) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); - if (!is_gimple_call (stmt) || gimple_no_warning_p (stmt)) + if (!is_gimple_call (stmt) || warning_suppressed_p (stmt, OPT_Wnonnull)) continue; tree fntype = gimple_call_fntype (stmt); diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index beb2702..db3b18b 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -403,7 +403,8 @@ combine_cond_expr_cond (gimple *stmt, enum tree_code code, tree type, return NULL_TREE; } - fold_undefer_overflow_warnings (!gimple_no_warning_p (stmt), stmt, 0); + bool nowarn = warning_suppressed_p (stmt, OPT_Wstrict_overflow); + fold_undefer_overflow_warnings (!nowarn, stmt, 0); return t; } diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index 08caa83..dfa5dc8 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -458,7 +458,7 @@ ch_base::copy_headers (function *fun) && gimple_cond_code (stmt) != NE_EXPR && INTEGRAL_TYPE_P (TREE_TYPE (lhs)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstrict_overflow_); } else if (is_gimple_assign (stmt)) { @@ -469,7 +469,7 @@ ch_base::copy_headers (function *fun) && rhs_code != NE_EXPR && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstrict_overflow_); } } } diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 7de47ed..48c952a 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -2143,7 +2143,7 @@ execute_sm (class loop *loop, im_mem_ref *ref, /* If not emitting a load mark the uninitialized state on the loop entry as not to be warned for. */ tree uninit = create_tmp_reg (TREE_TYPE (aux->tmp_var)); - TREE_NO_WARNING (uninit) = 1; + suppress_warning (uninit, OPT_Wuninitialized); load = gimple_build_assign (aux->tmp_var, uninit); } lim_data = init_lim_data (load); diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 02e26f9..ce5f0d5 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -2963,9 +2963,12 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, new_stmt = gimple_build_assign (name, lhs); gimple_set_location (new_stmt, locus); lhs = unshare_expr (lhs); - /* Set TREE_NO_WARNING on the rhs of the load to avoid uninit - warnings. */ - TREE_NO_WARNING (gimple_assign_rhs1 (new_stmt)) = 1; + { + /* Set the no-warning bit on the rhs of the load to avoid uninit + warnings. */ + tree rhs1 = gimple_assign_rhs1 (new_stmt); + suppress_warning (rhs1, OPT_Wuninitialized); + } gsi_insert_on_edge (e1, new_stmt); /* 3) Create a PHI node at the join block, with one argument diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 6add8c9..13ea107 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1938,7 +1938,7 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry, strinfo *si = NULL, bool plus_one = false, bool rawmem = false) { - if (!len || gimple_no_warning_p (stmt)) + if (!len || warning_suppressed_p (stmt, OPT_Wstringop_overflow_)) return; /* The DECL of the function performing the write if it is done @@ -1957,7 +1957,7 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry, else return; - if (TREE_NO_WARNING (dest)) + if (warning_suppressed_p (dest, OPT_Wstringop_overflow_)) return; const int ostype = rawmem ? 0 : 1; @@ -2101,7 +2101,7 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry, if (!warned) return; - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overflow_); aref.inform_access (access_write_only); } @@ -2624,16 +2624,16 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi, len = fold_convert_loc (loc, type, unshare_expr (srclen)); len = fold_build2_loc (loc, PLUS_EXPR, type, len, build_int_cst (type, 1)); - /* Set the no-warning bit on the transformed statement? */ - bool set_no_warning = false; + /* Disable warning for the transformed statement? */ + opt_code no_warning_opt = no_warning; - if (const strinfo *chksi = olddsi ? olddsi : dsi) - if (si - && check_bounds_or_overlap (stmt, chksi->ptr, si->ptr, NULL_TREE, len)) - { - gimple_set_no_warning (stmt, true); - set_no_warning = true; - } + if (const strinfo *chksi = si ? olddsi ? olddsi : dsi : NULL) + { + no_warning_opt = check_bounds_or_overlap (stmt, chksi->ptr, si->ptr, + NULL_TREE, len); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); + } if (fn == NULL_TREE) return; @@ -2667,8 +2667,8 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi, else if (dump_file && (dump_flags & TDF_DETAILS) != 0) fprintf (dump_file, "not possible.\n"); - if (set_no_warning) - gimple_set_no_warning (stmt, true); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } /* Check the size argument to the built-in forms of stpncpy and strncpy @@ -2796,7 +2796,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, pointer_query *ptr_qry /* = NULL */) { gimple *stmt = gsi_stmt (gsi); - if (gimple_no_warning_p (stmt)) + if (warning_suppressed_p (stmt, OPT_Wstringop_truncation)) return false; wide_int cntrange[2]; @@ -3156,9 +3156,10 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) else srclenp1 = NULL_TREE; - if (check_bounds_or_overlap (stmt, dst, src, dstlenp1, srclenp1)) + opt_code opt = check_bounds_or_overlap (stmt, dst, src, dstlenp1, srclenp1); + if (opt != no_warning) { - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, opt); return; } @@ -3169,7 +3170,7 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) if (!pss || pss->first <= 0) { if (maybe_diag_stxncpy_trunc (*gsi, src, len)) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_truncation); return; } @@ -3206,8 +3207,8 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) /* Issue -Wstringop-overflow when appending or when writing into a destination of a known size. Otherwise, when copying into a destination of an unknown size, it's truncation. */ - int opt = (append_p || dstsize - ? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation); + opt_code opt = (append_p || dstsize + ? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation); warned = warning_at (callloc, opt, "%G%qD specified bound depends on the length " "of the source argument", @@ -3448,8 +3449,8 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, srclen = get_string_length (si); } - /* Set the no-warning bit on the transformed statement? */ - bool set_no_warning = false; + /* Disable warning for the transformed statement? */ + opt_code no_warning_opt = no_warning; if (dsi == NULL || get_string_length (dsi) == NULL_TREE) { @@ -3466,12 +3467,10 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, } tree sptr = si && si->ptr ? si->ptr : src; - - if (check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE, slen)) - { - gimple_set_no_warning (stmt, true); - set_no_warning = true; - } + no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE, + slen); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } /* strcat (p, q) can be transformed into @@ -3578,11 +3577,10 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, tree dstsize = fold_build2 (PLUS_EXPR, type, dstlen, one); tree sptr = si && si->ptr ? si->ptr : src; - if (check_bounds_or_overlap (stmt, dst, sptr, dstsize, srcsize)) - { - gimple_set_no_warning (stmt, true); - set_no_warning = true; - } + no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, dstsize, + srcsize); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } tree len = NULL_TREE; @@ -3648,8 +3646,8 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, else if (dump_file && (dump_flags & TDF_DETAILS) != 0) fprintf (dump_file, "not possible.\n"); - if (set_no_warning) - gimple_set_no_warning (stmt, true); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } /* Handle a call to an allocation function like alloca, malloc or calloc, diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 7c002f8..99442d7 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -87,17 +87,33 @@ has_undefined_value_p (tree t) && possibly_undefined_names->contains (t))); } -/* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING - is set on SSA_NAME_VAR. */ +/* Return true if EXPR should suppress either uninitialized warning. */ + +static inline bool +get_no_uninit_warning (tree expr) +{ + return warning_suppressed_p (expr, OPT_Wuninitialized); +} + +/* Suppress both uninitialized warnings for EXPR. */ + +static inline void +set_no_uninit_warning (tree expr) +{ + suppress_warning (expr, OPT_Wuninitialized); +} + +/* Like has_undefined_value_p, but don't return true if the no-warning + bit is set on SSA_NAME_VAR for either uninit warning. */ static inline bool uninit_undefined_value_p (tree t) { if (!has_undefined_value_p (t)) return false; - if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t))) - return false; - return true; + if (!SSA_NAME_VAR (t)) + return true; + return !get_no_uninit_warning (SSA_NAME_VAR (t)); } /* Emit warnings for uninitialized variables. This is done in two passes. @@ -165,10 +181,10 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var, /* TREE_NO_WARNING either means we already warned, or the front end wishes to suppress the warning. */ if ((context - && (gimple_no_warning_p (context) + && (warning_suppressed_p (context, OPT_Wuninitialized) || (gimple_assign_single_p (context) - && TREE_NO_WARNING (gimple_assign_rhs1 (context))))) - || TREE_NO_WARNING (expr)) + && get_no_uninit_warning (gimple_assign_rhs1 (context))))) + || get_no_uninit_warning (expr)) return; if (context != NULL && gimple_has_location (context)) @@ -185,7 +201,7 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var, auto_diagnostic_group d; if (warning_at (location, wc, gmsgid, expr)) { - TREE_NO_WARNING (expr) = 1; + suppress_warning (expr, wc); if (location == DECL_SOURCE_LOCATION (var)) return; @@ -260,7 +276,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, use_operand_p luse_p; imm_use_iterator liter; - if (TREE_NO_WARNING (rhs)) + if (get_no_uninit_warning (rhs)) return NULL_TREE; /* Do not warn if the base was marked so or this is a @@ -268,7 +284,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, tree base = ao_ref_base (&ref); if ((VAR_P (base) && DECL_HARD_REGISTER (base)) - || TREE_NO_WARNING (base)) + || get_no_uninit_warning (base)) return NULL_TREE; /* Do not warn if the access is fully outside of the variable. */ @@ -407,7 +423,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, rhs = TREE_OPERAND (rhs, 0); /* Check again since RHS may have changed above. */ - if (TREE_NO_WARNING (rhs)) + if (get_no_uninit_warning (rhs)) return NULL_TREE; /* Avoid warning about empty types such as structs with no members. @@ -435,7 +451,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, uses or accesses by functions as it may hide important locations. */ if (lhs) - TREE_NO_WARNING (rhs) = 1; + set_no_uninit_warning (rhs); warned = true; } } diff --git a/gcc/tree-vect-slp-patterns.c b/gcc/tree-vect-slp-patterns.c index d536494..2671f91 100644 --- a/gcc/tree-vect-slp-patterns.c +++ b/gcc/tree-vect-slp-patterns.c @@ -1577,11 +1577,13 @@ addsub_pattern::build (vec_info *vinfo) (TREE_TYPE (gimple_assign_lhs (rep->stmt)))); gimple_call_set_nothrow (call, true); gimple_set_bb (call, gimple_bb (rep->stmt)); - SLP_TREE_REPRESENTATIVE (node) = vinfo->add_pattern_stmt (call, rep); - STMT_VINFO_RELEVANT (SLP_TREE_REPRESENTATIVE (node)) = vect_used_in_scope; - STMT_SLP_TYPE (SLP_TREE_REPRESENTATIVE (node)) = pure_slp; - STMT_VINFO_VECTYPE (SLP_TREE_REPRESENTATIVE (node)) = SLP_TREE_VECTYPE (node); - STMT_VINFO_SLP_VECT_ONLY_PATTERN (SLP_TREE_REPRESENTATIVE (node)) = true; + stmt_vec_info new_rep = vinfo->add_pattern_stmt (call, rep); + SLP_TREE_REPRESENTATIVE (node) = new_rep; + STMT_VINFO_RELEVANT (new_rep) = vect_used_in_scope; + STMT_SLP_TYPE (new_rep) = pure_slp; + STMT_VINFO_VECTYPE (new_rep) = SLP_TREE_VECTYPE (node); + STMT_VINFO_SLP_VECT_ONLY_PATTERN (new_rep) = true; + STMT_VINFO_REDUC_DEF (new_rep) = STMT_VINFO_REDUC_DEF (vect_orig_stmt (rep)); SLP_TREE_CODE (node) = ERROR_MARK; SLP_TREE_LANE_PERMUTATION (node).release (); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b9c0e65..0565c9b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -406,10 +406,10 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) return -2; if (strict_overflow_p != NULL - /* Symbolic range building sets TREE_NO_WARNING to declare + /* Symbolic range building sets the no-warning bit to declare that overflow doesn't happen. */ - && (!inv1 || !TREE_NO_WARNING (val1)) - && (!inv2 || !TREE_NO_WARNING (val2))) + && (!inv1 || !warning_suppressed_p (val1, OPT_Woverflow)) + && (!inv2 || !warning_suppressed_p (val2, OPT_Woverflow))) *strict_overflow_p = true; if (!inv1) @@ -432,10 +432,10 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) return -2; if (strict_overflow_p != NULL - /* Symbolic range building sets TREE_NO_WARNING to declare + /* Symbolic range building sets the no-warning bit to declare that overflow doesn't happen. */ - && (!sym1 || !TREE_NO_WARNING (val1)) - && (!sym2 || !TREE_NO_WARNING (val2))) + && (!sym1 || !warning_suppressed_p (val1, OPT_Woverflow)) + && (!sym2 || !warning_suppressed_p (val2, OPT_Woverflow))) *strict_overflow_p = true; const signop sgn = TYPE_SIGN (TREE_TYPE (val1)); @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_TREE_H #include "tree-core.h" +#include "options.h" /* Convert a target-independent built-in function code to a combined_fn. */ @@ -6441,4 +6442,30 @@ public: operator location_t () const { return m_combined_loc; } }; +/* Code that doesn't refer to any warning. Has no effect on suppression + functions. */ +constexpr opt_code no_warning = opt_code (); +/* Wildcard code that refers to all warnings. */ +constexpr opt_code all_warnings = N_OPTS; + +/* Return the disposition for a warning (or all warnings by default) + at a location. */ +extern bool warning_suppressed_at (location_t, opt_code = all_warnings); +/* Set the disposition for a warning (or all warnings by default) + at a location to disabled by default. */ +extern bool suppress_warning_at (location_t, opt_code = all_warnings, + bool = true); +/* Copy warning disposition from one location to another. */ +extern void copy_warning (location_t, location_t); + +/* Return the disposition for a warning (or all warnings by default) + for an expression. */ +extern bool warning_suppressed_p (const_tree, opt_code = all_warnings); +/* Set the disposition for a warning (or all warnings by default) + at a location to disabled by default. */ +extern void suppress_warning (tree, opt_code = all_warnings, bool = true) + ATTRIBUTE_NONNULL (1); +/* Copy warning disposition from one expression to another. */ +extern void copy_warning (tree, const_tree); + #endif /* GCC_TREE_H */ diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 3c8698f..43fcab7 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -444,7 +444,7 @@ equiv_oracle::dump (FILE *f) const { fprintf (f, "Equivalency dump\n"); for (unsigned i = 0; i < m_equiv.length (); i++) - if (m_equiv[i]) + if (m_equiv[i] && BASIC_BLOCK_FOR_FN (cfun, i)) { fprintf (f, "BB%d\n", i); dump (f, BASIC_BLOCK_FOR_FN (cfun, i)); @@ -757,9 +757,9 @@ relation_oracle::find_relation_block (unsigned bb, const_bitmap b1, { unsigned op1 = SSA_NAME_VERSION (ptr->op1 ()); unsigned op2 = SSA_NAME_VERSION (ptr->op2 ()); - if (bitmap_bit_p (b1, op1) && bitmap_bit_p (b1, op2)) + if (bitmap_bit_p (b1, op1) && bitmap_bit_p (b2, op2)) return ptr->kind (); - if (bitmap_bit_p (b1, op2) && bitmap_bit_p (b1, op1)) + if (bitmap_bit_p (b1, op2) && bitmap_bit_p (b2, op1)) return relation_swap (ptr->kind ()); } @@ -925,8 +925,9 @@ relation_oracle::dump (FILE *f) const { fprintf (f, "Relation dump\n"); for (unsigned i = 0; i < m_relations.length (); i++) - { - fprintf (f, "BB%d\n", i); - dump (f, BASIC_BLOCK_FOR_FN (cfun, i)); - } + if (BASIC_BLOCK_FOR_FN (cfun, i)) + { + fprintf (f, "BB%d\n", i); + dump (f, BASIC_BLOCK_FOR_FN (cfun, i)); + } } diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 509c8b0..3ae2c68 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -699,7 +699,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, build_int_cst (TREE_TYPE (max), 1)); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (max)) - TREE_NO_WARNING (max) = 1; + suppress_warning (max, OPT_Woverflow); } vr_p->update (min, max); @@ -739,7 +739,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, build_int_cst (TREE_TYPE (min), 1)); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (min)) - TREE_NO_WARNING (min) = 1; + suppress_warning (min, OPT_Woverflow); } vr_p->update (min, max); @@ -3355,7 +3355,7 @@ test_for_singularity (enum tree_code cond_code, tree op0, max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (max)) - TREE_NO_WARNING (max) = 1; + suppress_warning (max, OPT_Woverflow); } } else if (cond_code == GE_EXPR || cond_code == GT_EXPR) @@ -3369,7 +3369,7 @@ test_for_singularity (enum tree_code cond_code, tree op0, min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (min)) - TREE_NO_WARNING (min) = 1; + suppress_warning (min, OPT_Woverflow); } } diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc new file mode 100644 index 0000000..ec8ed232 --- /dev/null +++ b/gcc/warning-control.cc @@ -0,0 +1,238 @@ +/* Functions to enable and disable individual warnings on an expression + and statement basis. + + Copyright (C) 2021 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC 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 General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "bitmap.h" +#include "tree.h" +#include "gimple.h" +#include "cgraph.h" +#include "hash-map.h" +#include "diagnostic-spec.h" + +/* Return the no-warning bit for EXPR. */ + +static inline bool +get_no_warning_bit (const_tree expr) +{ + return expr->base.nowarning_flag; +} + +/* Return the no-warning bit for statement STMT. */ + +static inline bool +get_no_warning_bit (const gimple *stmt) +{ + return stmt->no_warning; +} + +/* Set the no-warning bit for EXPR to VALUE. */ + +static inline void +set_no_warning_bit (tree expr, bool value) +{ + expr->base.nowarning_flag = value; +} + +/* Set the no-warning bit for statement STMT to VALUE. */ + +static inline void +set_no_warning_bit (gimple *stmt, bool value) +{ + stmt->no_warning = value; +} + +/* Return EXPR location or zero. */ + +static inline key_type_t +convert_to_key (const_tree expr) +{ + if (DECL_P (expr)) + return DECL_SOURCE_LOCATION (expr); + if (EXPR_P (expr)) + return EXPR_LOCATION (expr); + return 0; +} + +/* Return STMT location (may be zero). */ + +static inline key_type_t +convert_to_key (const gimple *stmt) +{ + return gimple_location (stmt); +} + +/* Return the no-warning bitmap for decl/expression EXPR. */ + +static nowarn_spec_t * +get_nowarn_spec (const_tree expr) +{ + const key_type_t key = convert_to_key (expr); + + if (!get_no_warning_bit (expr) || !key) + return NULL; + + return nowarn_map ? nowarn_map->get (key) : NULL; +} + +/* Return the no-warning bitmap for stateemt STMT. */ + +static nowarn_spec_t * +get_nowarn_spec (const gimple *stmt) +{ + const key_type_t key = convert_to_key (stmt); + + if (!get_no_warning_bit (stmt)) + return NULL; + + return nowarn_map ? nowarn_map->get (key) : NULL; +} + +/* Return true if warning OPT is suppressed for decl/expression EXPR. + By default tests the disposition for any warning. */ + +bool +warning_suppressed_p (const_tree expr, opt_code opt /* = all_warnings */) +{ + const nowarn_spec_t *spec = get_nowarn_spec (expr); + + if (!spec) + return get_no_warning_bit (expr); + + const nowarn_spec_t optspec (opt); + bool dis = *spec & optspec; + gcc_assert (get_no_warning_bit (expr) || !dis); + return dis; +} + +/* Return true if warning OPT is suppressed for statement STMT. + By default tests the disposition for any warning. */ + +bool +warning_suppressed_p (const gimple *stmt, opt_code opt /* = all_warnings */) +{ + const nowarn_spec_t *spec = get_nowarn_spec (stmt); + + if (!spec) + /* Fall back on the single no-warning bit. */ + return get_no_warning_bit (stmt); + + const nowarn_spec_t optspec (opt); + bool dis = *spec & optspec; + gcc_assert (get_no_warning_bit (stmt) || !dis); + return dis; +} + +/* Enable, or by default disable, a warning for the expression. + The wildcard OPT of -1 controls all warnings. */ + +void +suppress_warning (tree expr, opt_code opt /* = all_warnings */, + bool supp /* = true */) +{ + if (opt == no_warning) + return; + + const key_type_t key = convert_to_key (expr); + + supp = suppress_warning_at (key, opt, supp) || supp; + set_no_warning_bit (expr, supp); +} + +/* Enable, or by default disable, a warning for the statement STMT. + The wildcard OPT of -1 controls all warnings. */ + +void +suppress_warning (gimple *stmt, opt_code opt /* = all_warnings */, + bool supp /* = true */) +{ + if (opt == no_warning) + return; + + const key_type_t key = convert_to_key (stmt); + + supp = suppress_warning_at (key, opt, supp) || supp; + set_no_warning_bit (stmt, supp); +} + +/* Copy the warning disposition mapping between an expression and/or + a statement. */ + +template <class ToType, class FromType> +void copy_warning (ToType to, FromType from) +{ + const key_type_t to_key = convert_to_key (to); + + if (nowarn_spec_t *from_map = get_nowarn_spec (from)) + { + /* If there's an entry in the map the no-warning bit must be set. */ + gcc_assert (get_no_warning_bit (from)); + + if (!nowarn_map) + nowarn_map = xint_hash_map_t::create_ggc (32); + + nowarn_map->put (to_key, *from_map); + set_no_warning_bit (to, true); + } + else + { + if (nowarn_map) + nowarn_map->remove (to_key); + + /* The no-warning bit might be set even if there's no entry + in the map. */ + set_no_warning_bit (to, get_no_warning_bit (from)); + } +} + +/* Copy the warning disposition mapping from one expression to another. */ + +void +copy_warning (tree to, const_tree from) +{ + copy_warning<tree, const_tree>(to, from); +} + +/* Copy the warning disposition mapping from a statement to an expression. */ + +void +copy_warning (tree to, const gimple *from) +{ + copy_warning<tree, const gimple *>(to, from); +} + +/* Copy the warning disposition mapping from an expression to a statement. */ + +void +copy_warning (gimple *to, const_tree from) +{ + copy_warning<gimple *, const_tree>(to, from); +} + +/* Copy the warning disposition mapping from one statement to another. */ + +void +copy_warning (gimple *to, const gimple *from) +{ + copy_warning<gimple *, const gimple *>(to, from); +} diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 6a87abb..640d6fa 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,10 @@ +2021-06-24 Jakub Jelinek <jakub@redhat.com> + + * testsuite/libgomp.c-c++-common/target-in-reduction-1.c: New test. + * testsuite/libgomp.c-c++-common/target-in-reduction-2.c: New test. + * testsuite/libgomp.c++/target-in-reduction-1.C: New test. + * testsuite/libgomp.c++/target-in-reduction-2.C: New test. + 2021-06-23 Jakub Jelinek <jakub@redhat.com> PR middle-end/101167 diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0835510..58d591c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,89 @@ +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_math.h + (_GLIBCXX_SIMD_MATH_CALL2_): Rename arg2_ to __arg2. + (_GLIBCXX_SIMD_MATH_CALL3_): Rename arg2_ to __arg2 and arg3_ to + __arg3. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd.h (__execute_on_index_sequence) + (__execute_on_index_sequence_with_return) + (__call_with_n_evaluations, __call_with_subscripts): Add flatten + attribute. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_x86.h (_S_trunc, _S_floor) + (_S_ceil): Set bit 8 (_MM_FROUND_NO_EXC) on AVX and SSE4.1 + roundp[sd] calls. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_x86.h (_S_ldexp): The AVX512F + implementation doesn't require a _VecBltnBtmsk ABI tag, it + requires either a 64-Byte input (in which case AVX512F must be + available) or AVX512VL. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_math.h: Undefine internal + macros after use. + (frexp): Move #if to a more sensible position and reformat + preceding code. + (logb): Call _SimdImpl::_S_logb for fixed_size instead of + duplicating the code here. + (modf): Simplify condition. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_math.h (fabs): Remove + fabs(simd<integral>) overload. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_converter.h + (_SimdConverter::operator()): Pass _SimdTuple by const-ref. + * include/experimental/bits/simd_fixed_size.h + (_GLIBCXX_SIMD_FIXED_OP): Pass binary operator _SimdTuple + arguments by const-ref. + (_S_masked_unary): Pass _SimdTuple by const-ref. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd_fixed_size.h + (_AbisInSimdTuple): Removed. + +2021-06-24 Matthias Kretz <m.kretz@gsi.de> + + * include/experimental/bits/simd.h: Add missing operator~ + overload for simd<floating-point> to __float_bitwise_operators. + * include/experimental/bits/simd_builtin.h + (_SimdImplBuiltin::_S_complement): Bitcast to int (and back) to + implement complement for floating-point vectors. + * include/experimental/bits/simd_fixed_size.h + (_SimdImplFixedSize::_S_copysign): New function, forwarding to + copysign implementation of _SimdTuple members. + * include/experimental/bits/simd_math.h (copysign): Call + _SimdImpl::_S_copysign for fixed_size arguments. Simplify + generic copysign implementation using the new ~ operator. + +2021-06-24 Jonathan Wakely <jwakely@redhat.com> + + * testsuite/experimental/simd/README.md: Fix typos. + +2021-06-24 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/shared_ptr_base.h (__shared_ptr_access::operator[]): + Add noexcept. + * include/bits/unique_ptr.h (unique_ptr::operator*): Add + conditional noexcept as per LWG 2762. + * testsuite/20_util/shared_ptr/observers/array.cc: Check that + dereferencing cannot throw. + * testsuite/20_util/shared_ptr/observers/get.cc: Likewise. + * testsuite/20_util/optional/observers/lwg2762.cc: New test. + * testsuite/20_util/unique_ptr/lwg2762.cc: New test. + 2021-06-23 Patrick Palka <ppalka@redhat.com> PR c++/101174 diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c index ff79f4a..6ab9822 100644 --- a/lto-plugin/lto-plugin.c +++ b/lto-plugin/lto-plugin.c @@ -190,6 +190,8 @@ static int lto_wrapper_num_args; static char **pass_through_items = NULL; static unsigned int num_pass_through_items; +static char *ltrans_objects = NULL; + static bool debug; static bool save_temps; static bool verbose; @@ -739,6 +741,14 @@ all_symbols_read_handler (void) return LDPS_OK; } + if (ltrans_objects) + { + FILE *objs = fopen (ltrans_objects, "r"); + add_output_files (objs); + fclose (objs); + return LDPS_OK; + } + lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args); lto_arg_ptr = (const char **) lto_argv; assert (lto_wrapper_argv); @@ -1345,6 +1355,8 @@ process_option (const char *option) break; } } + else if (startswith (option, "-ltrans-objects=")) + ltrans_objects = xstrdup (option + strlen ("-ltrans-objects=")); else { int size; |