aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-01-28 14:08:09 +0100
committerMartin Liska <mliska@suse.cz>2022-01-28 14:08:09 +0100
commitf015156d6662c3ce367c5834eb109a0a77b56f39 (patch)
treee296374325c59068a60eb7a6b9ec721d1c931750 /gcc
parent58446a69f792166ea2e12d44d5bb3ef1aa61c00d (diff)
parent9ec306582fd60e5b76f07eb81c9ed2415d9a3590 (diff)
downloadgcc-f015156d6662c3ce367c5834eb109a0a77b56f39.zip
gcc-f015156d6662c3ce367c5834eb109a0a77b56f39.tar.gz
gcc-f015156d6662c3ce367c5834eb109a0a77b56f39.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog276
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/exp_ch4.adb6
-rw-r--r--gcc/analyzer/ChangeLog74
-rw-r--r--gcc/analyzer/checker-path.cc41
-rw-r--r--gcc/analyzer/checker-path.h21
-rw-r--r--gcc/analyzer/constraint-manager.cc95
-rw-r--r--gcc/analyzer/diagnostic-manager.cc74
-rw-r--r--gcc/analyzer/diagnostic-manager.h3
-rw-r--r--gcc/analyzer/pending-diagnostic.cc32
-rw-r--r--gcc/analyzer/pending-diagnostic.h24
-rw-r--r--gcc/analyzer/region-model-manager.cc4
-rw-r--r--gcc/analyzer/region-model.cc54
-rw-r--r--gcc/analyzer/region-model.h3
-rw-r--r--gcc/analyzer/region.h1
-rw-r--r--gcc/builtins.cc79
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c.opt13
-rw-r--r--gcc/cfganal.cc28
-rw-r--r--gcc/cfganal.h1
-rw-r--r--gcc/cfgrtl.cc27
-rw-r--r--gcc/config/riscv/riscv.md2
-rw-r--r--gcc/config/rs6000/aix.h1
-rw-r--r--gcc/config/rs6000/bmi2intrin.h7
-rw-r--r--gcc/config/rs6000/bmiintrin.h4
-rw-r--r--gcc/config/rs6000/emmintrin.h2
-rw-r--r--gcc/config/rs6000/rs6000-call.cc12
-rw-r--r--gcc/config/rs6000/rs6000-internal.h3
-rw-r--r--gcc/config/rs6000/rs6000.cc60
-rw-r--r--gcc/config/rs6000/rs6000.md111
-rw-r--r--gcc/config/rs6000/smmintrin.h3
-rw-r--r--gcc/cp/ChangeLog90
-rw-r--r--gcc/cp/call.cc43
-rw-r--r--gcc/cp/constexpr.cc7
-rw-r--r--gcc/cp/decl.cc14
-rw-r--r--gcc/cp/decl2.cc18
-rw-r--r--gcc/cp/optimize.cc1
-rw-r--r--gcc/cp/parser.cc40
-rw-r--r--gcc/cp/pt.cc42
-rw-r--r--gcc/cp/semantics.cc5
-rw-r--r--gcc/cp/tree.cc5
-rw-r--r--gcc/cp/typeck.cc19
-rw-r--r--gcc/diagnostic.cc22
-rw-r--r--gcc/diagnostic.h3
-rw-r--r--gcc/doc/extend.texi8
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/doc/md.texi17
-rw-r--r--gcc/dwarf2out.cc68
-rw-r--r--gcc/fortran/ChangeLog41
-rw-r--r--gcc/fortran/check.cc8
-rw-r--r--gcc/fortran/expr.cc3
-rw-r--r--gcc/fortran/target-memory.cc7
-rw-r--r--gcc/fortran/trans-array.cc74
-rw-r--r--gcc/fortran/trans-intrinsic.cc53
-rw-r--r--gcc/gimple-fold.cc26
-rw-r--r--gcc/gimple-fold.h2
-rw-r--r--gcc/gimple-ssa-warn-access.cc16
-rw-r--r--gcc/gimplify.cc5
-rw-r--r--gcc/graph.cc15
-rw-r--r--gcc/ipa-modref-tree.cc10
-rw-r--r--gcc/ipa-modref-tree.h9
-rw-r--r--gcc/optabs.def4
-rw-r--r--gcc/opts.cc4
-rw-r--r--gcc/pointer-query.cc74
-rw-r--r--gcc/pointer-query.h2
-rw-r--r--gcc/testsuite/ChangeLog271
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-10.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-11.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-14.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-16.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-17.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-18.c11
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-19.c11
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-20.c11
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-21.c11
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-22.c11
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-23.c11
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-4.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-5.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-6.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-7.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-8.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-9.c2
-rw-r--r--gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr103642.c34
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-void1.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-104226.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template21.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-template21a.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/ref-qual21.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction-new1.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction104.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction105.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp23/auto-array2.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec11.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval-memfn2.C34
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/consteval28.C10
-rw-r--r--gcc/testsuite/g++.dg/init/assign2.C6
-rw-r--r--gcc/testsuite/g++.dg/lto/alignas1_0.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/template-keyword2.C8
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuse-after-free2.C10
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuse-after-free3.C16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr104196.c19
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr101547.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr101875.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr101962.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104224.c106
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94047.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/zlib-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/inline-13.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-8.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr81196-2.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr104188.c3
-rw-r--r--gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-1.c76
-rw-r--r--gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-2.c91
-rw-r--r--gcc/testsuite/gcc.target/powerpc/builtin-fegetround.c36
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr103702.c24
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr104239-1.c10
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr104239-2.c10
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr104239-3.c8
-rw-r--r--gcc/testsuite/gfortran.dg/argument_checking_26.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_collectives_18.f9037
-rw-r--r--gcc/testsuite/gfortran.dg/ieee/signaling_1.f907
-rw-r--r--gcc/testsuite/gfortran.dg/ieee/signaling_2.f904
-rw-r--r--gcc/testsuite/gfortran.dg/ieee/signaling_3.f9043
-rw-r--r--gcc/testsuite/gfortran.dg/pr84784.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_check_6.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_simplify_14.f9027
-rw-r--r--gcc/testsuite/gnat.dg/generic_comp.adb39
-rw-r--r--gcc/timevar.def1
-rw-r--r--gcc/tree-cfg.cc4
-rw-r--r--gcc/tree-ssa-loop-niter.cc15
-rw-r--r--gcc/tree-ssa-reassoc.cc89
-rw-r--r--gcc/tree-vect-stmts.cc4
-rw-r--r--gcc/tree.cc2
-rw-r--r--gcc/tree.h2
154 files changed, 2977 insertions, 391 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a7842c..7b9ef63 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,279 @@
+2022-01-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/99895
+ * tree.cc (build_call_vec): Add const to second parameter.
+ * tree.h (build_call_vec): Likewise.
+
+2022-01-27 Martin Liska <mliska@suse.cz>
+
+ PR web/104254
+ * diagnostic.cc (diagnostic_initialize):
+ Initialize report_bug flag.
+ (diagnostic_action_after_output):
+ Explain that -freport-bug option can be used for pre-processed
+ file creation. Make the message shorter.
+ (error_recursion): Rename Internal to internal.
+ * diagnostic.h (struct diagnostic_context): New field.
+ * opts.cc (common_handle_option): Init the field here.
+
+2022-01-27 Kewen Lin <linkw@linux.ibm.com>
+
+ PR target/103702
+ * config/rs6000/rs6000.cc
+ (rs6000_cost_data::update_target_cost_per_stmt): Fix one wrong
+ assertion with early return.
+
+2022-01-27 Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR middle-end/103642
+ * gimplify.cc (gimplify_scan_omp_clauses): Do not do indir_p handling
+ for non-pointer or non-reference-to-pointer cases.
+
+2022-01-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/104196
+ * gimple-fold.h (rewrite_to_defined_overflow): Add IN_PLACE argument.
+ * gimple-fold.cc (rewrite_to_defined_overflow): Likewise. If true,
+ return NULL and emit needed stmts before and after stmt.
+ * tree-ssa-reassoc.cc (update_range_test): For inter-bb range opt
+ pick as operand_entry that will hold the merged test the one feeding
+ earliest condition, ensure that by swapping range->idx with some
+ other range's idx if needed. If seq is non-NULL, don't actually swap
+ it but instead rewrite stmts with undefined overflow in between
+ the two locations.
+ (maybe_optimize_range_tests): Set ops[]->id to bb->index with the
+ corresponding condition even if they have non-NULL ops[]->op.
+ Formatting fix.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104239
+ * config/rs6000/emmintrin.h (_mm_sad_epu8): Use __asm__ instead of
+ asm.
+ * config/rs6000/smmintrin.h (_mm_minpos_epu16): Declare iterator
+ before for loop instead of for init clause.
+ * config/rs6000/bmi2intrin.h (_pext_u64): Likewise.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104239
+ * config/rs6000/bmiintrin.h: Test _X86GPRINTRIN_H_INCLUDED instead of
+ _X86INTRIN_H_INCLUDED and adjust #error wording.
+ * config/rs6000/bmi2intrin.h: Likewise.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/104194
+ * dwarf2out.cc (long_double_as_float128): New function.
+ (modified_type_die): For powerpc64le IEEE 754 quad long double
+ and complex long double emit those as DW_TAG_typedef to
+ _Float128 or complex _Float128 base type.
+
+2022-01-26 Marek Polacek <polacek@redhat.com>
+
+ PR target/104213
+ * gimple-ssa-warn-access.cc (pass_waccess::warn_invalid_pointer): Don't
+ warn when the SSA_NAME_VAR of REF has supressed -Wuse-after-free.
+
+2022-01-26 Martin Liska <mliska@suse.cz>
+
+ * ipa-modref-tree.cc (modref_access_node::update):
+ Remove "--param param=foo" with "--param foo".
+ (modref_access_node::insert): Likewise.
+ (modref_access_node::insert_kill): Likewise.
+ * ipa-modref-tree.h (struct modref_ref_node): Likewise.
+ (struct modref_base_node): Likewise.
+ (struct modref_tree): Likewise.
+
+2022-01-26 Raoni Fassina Firmino <raoni@linux.ibm.com>
+
+ PR target/94193
+ * builtins.cc (expand_builtin_feclear_feraise_except): Add op0
+ predicate check.
+
+2022-01-25 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/104203
+ * gimple-ssa-warn-access.cc (pass_data pass_data_waccess): Use
+ TV_WARN_ACCESS.
+ * pointer-query.cc (access_ref::merge_ref): Change return type.
+ Convert failure to a conservative success.
+ (access_ref::get_ref): Adjust to the change above. Short-circuit
+ PHI evaluation after first failure turned into conservative success.
+ * pointer-query.h (access_ref::merge_ref): Change return type.
+ * timevar.def (TV_WARN_ACCESS): New timer variable.
+
+2022-01-25 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/aix.h (OPTION_GLIBC): Define as 0.
+
+2022-01-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104214
+ * tree-ssa-loop-niter.cc (number_of_iterations_cond): Use
+ stronger guarantees for relational pointer compares when
+ rewriting BASE0 + STEP0 cmp BASE1 + STEP1 as
+ BASE0 + STEP0 - STEP1 cmp BASE1.
+
+2022-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104172
+ * config/rs6000/rs6000-internal.h (rs6000_passes_ieee128): Don't
+ declare.
+ * config/rs6000/rs6000.cc (rs6000_passes_ieee128,
+ ieee128_mangling_gcc_8_1): Remove.
+ (TARGET_ASM_GLOBALIZE_DECL_NAME): Don't redefine.
+ (rs6000_mangle_type): Return "u9__ieee128" instead of
+ ieee128_mangling_gcc_8_1 ? "U10__float128" : "u9__ieee128".
+ (rs6000_globalize_decl_name): Remove.
+ * config/rs6000/rs6000-call.cc (init_cumulative_args,
+ rs6000_function_arg_advance_1): Don't set rs6000_passes_ieee128.
+
+2022-01-24 Martin Sebor <msebor@redhat.com>
+
+ * pointer-query.cc (pointer_query::dump): Remove duplicate
+ block.
+
+2022-01-24 Marek Polacek <polacek@redhat.com>
+
+ PR preprocessor/104030
+ * doc/invoke.texi: Update documentation for -Wbidi-chars.
+
+2022-01-24 Raoni Fassina Firmino <raoni@linux.ibm.com>
+
+ PR target/94193
+ * builtins.cc (expand_builtin_fegetround): New function.
+ (expand_builtin_feclear_feraise_except): New function.
+ (expand_builtin): Add cases for BUILT_IN_FEGETROUND,
+ BUILT_IN_FECLEAREXCEPT and BUILT_IN_FERAISEEXCEPT.
+ * config/rs6000/rs6000.md (fegetroundsi): New pattern.
+ (feclearexceptsi): New Pattern.
+ (feraiseexceptsi): New Pattern.
+ * doc/extend.texi: Add a new introductory paragraph about the
+ new builtins.
+ * doc/md.texi: (fegetround@var{m}): Document new optab.
+ (feclearexcept@var{m}): Document new optab.
+ (feraiseexcept@var{m}): Document new optab.
+ * optabs.def (fegetround_optab): New optab.
+ (feclearexcept_optab): New optab.
+ (feraiseexcept_optab): New optab.
+
+2022-01-24 Richard Biener <rguenther@suse.de>
+ Jiufu Guo <guojiufu@linux.ibm.com>
+
+ PR tree-optimization/100740
+ PR tree-optimization/101508
+ PR tree-optimization/101972
+ PR tree-optimization/102131
+ * tree-ssa-loop-niter.cc (number_of_iterations_cond): Properly
+ constrain BASE0 + STEP0 cmp BASE1 + STEP1 to
+ BASE0 + STEP0 - STEP1 cmp BASE1 transform.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/104158
+ * opt-functions.awk (var_set): Handle EnumBitSet property.
+ * optc-gen.awk: Don't disallow RejectNegative if EnumBitSet is
+ specified.
+ * opts.h (enum cl_enum_var_value): New type.
+ * opts-common.cc (decode_cmdline_option): Use CLEV_* values.
+ Handle CLEV_BITSET.
+ (cmdline_handle_error): Handle CLEV_BITSET.
+ * opts.cc (test_enum_sets): Also test EnumBitSet requirements.
+ * doc/options.texi (EnumBitSet): Document.
+ * common.opt (fsanitize-coverage=): Use EnumBitSet instead of
+ EnumSet.
+ (trace-pc, trace-cmp): Drop Set properties.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/104158
+ * common.opt (flag_sanitize_coverage): Remove Variable entry.
+ (fsanitize-coverage=): Remove RejectNegative property, add
+ Var(flag_sanitize_coverage) and EnumSet properties.
+ (trace-pc): Add Set(1) property.
+ (trace-cmp): Add Set(2) property.
+ * opts.cc (common_handle_option): Don't handle
+ OPT_fsanitize_coverage_.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/104158
+ * opt-functions.awk (var_set): Handle EnumSet property.
+ * optc-gen.awk: Don't disallow RejectNegative if EnumSet is
+ specified.
+ * opt-read.awk: Handle Set property.
+ * opts.h (CL_ENUM_SET_SHIFT, CL_ERR_ENUM_SET_ARG): Define.
+ (struct cl_decoded_option): Mention enum in value description.
+ Add mask member.
+ (set_option): Add mask argument defaulted to 0.
+ * opts.cc (test_enum_sets): New function.
+ (opts_cc_tests): Call it.
+ * opts-common.cc (enum_arg_to_value): Change return argument
+ from bool to int, on success return index into the cl_enum_arg
+ array, on failure -1. Add len argument, if non-0, use strncmp
+ instead of strcmp.
+ (opt_enum_arg_to_value): Adjust caller.
+ (decode_cmdline_option): Handle EnumSet represented as
+ CLVC_ENUM with non-zero var_value. Initialize decoded->mask.
+ (decode_cmdline_options_to_array): CLear opt_array[0].mask.
+ (handle_option): Pass decoded->mask to set_options last argument.
+ (generate_option): Clear decoded->mask.
+ (generate_option_input_file): Likewise.
+ (cmdline_handle_error): Handle CL_ERR_ENUM_SET_ARG.
+ (set_option): Add mask argument, use it for CLVC_ENUM.
+ (control_warning_option): Adjust enum_arg_to_value caller.
+ * doc/options.texi: Document Set and EnumSet properties.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/104170
+ * config/linux.h (OPTION_GLIBC_P, OPTION_UCLIBC_P,
+ OPTION_BIONIC_P, OPTION_MUSL_P): Define.
+ (OPTION_GLIBC, OPTION_UCLIBC, OPTION_BIONIC, OPTION_MUSL): Redefine
+ using OPTION_*_P macros.
+ * config/alpha/linux.h (OPTION_GLIBC_P, OPTION_UCLIBC_P,
+ OPTION_BIONIC_P, OPTION_MUSL_P): Define.
+ (OPTION_GLIBC, OPTION_UCLIBC, OPTION_BIONIC, OPTION_MUSL): Redefine
+ using OPTION_*_P macros.
+ * config/rs6000/linux.h (OPTION_GLIBC_P, OPTION_UCLIBC_P,
+ OPTION_BIONIC_P, OPTION_MUSL_P): Define.
+ (OPTION_GLIBC, OPTION_UCLIBC, OPTION_BIONIC, OPTION_MUSL): Redefine
+ using OPTION_*_P macros.
+ * config/rs6000/linux64.h (OPTION_GLIBC_P, OPTION_UCLIBC_P,
+ OPTION_BIONIC_P, OPTION_MUSL_P): Define.
+ (OPTION_GLIBC, OPTION_UCLIBC, OPTION_BIONIC, OPTION_MUSL): Redefine
+ using OPTION_*_P macros.
+ * config/fuchsia.h (OPTION_MUSL_P): Redefine.
+ * config/glibc-stdint.h (OPTION_MUSL_P): Define if not defined.
+ * common/config/s390/s390-common.cc (s390_supports_split_stack): Re-add
+ ATTRIBUTE_UNUSED to opts parameter. If OPTION_GLIBC_P is defined, use
+ OPTION_GLIBC_P (opts) as condition, otherwise assume if (false).
+ * common/config/i386/i386-common.cc (ix86_supports_split_stack): If
+ OPTION_GLIBC_P is defined use !OPTION_GLIBC_P (opts) as condition,
+ otherwise assume if (true).
+
+2022-01-24 Kito Cheng <kito.cheng@sifive.com>
+
+ * common/config/riscv/riscv-common.cc (riscv_subset_list::to_string):
+ Skip zicsr and zifencei if I-ext is 2.0.
+
+2022-01-24 Jia-Wei Chen <jiawei@iscas.ac.cn>
+
+ * config.gcc: Modify default isa_spec version.
+
+2022-01-24 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ PR tree-optimization/102087
+ * tree-ssa-loop-niter.cc (number_of_iterations_until_wrap):
+ Correct PLUS result type.
+
+2022-01-24 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/104188
+ * config/i386/predicates.md (bcst_mem_operand): Also check mode
+ of memory broadcast.
+
2022-01-23 Andrew Pinski <apinski@marvell.com>
PR target/64821
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index da164bf..5f74118 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220124
+20220128
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index c31f5bb..2506c67 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -14314,9 +14314,13 @@ package body Exp_Ch4 is
return;
end if;
- -- Finally, rewrite the operation in the narrower type
+ -- Finally, rewrite the operation in the narrower type, but make sure
+ -- not to perform name resolution for the operator again.
Nop := New_Op_Node (Kind, Sloc (N));
+ if Nkind (N) in N_Has_Entity then
+ Set_Entity (Nop, Entity (N));
+ end if;
if Binary then
Set_Left_Opnd (Nop, Convert_To (Ntyp, L));
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 4df447d..167f1b8 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,77 @@
+2022-01-27 David Malcolm <dmalcolm@redhat.com>
+
+ * checker-path.cc (event_kind_to_string): Handle
+ EK_REGION_CREATION.
+ (region_creation_event::region_creation_event): New.
+ (region_creation_event::get_desc): New.
+ (checker_path::add_region_creation_event): New.
+ * checker-path.h (enum event_kind): Add EK_REGION_CREATION.
+ (class region_creation_event): New subclass.
+ (checker_path::add_region_creation_event): New decl.
+ * diagnostic-manager.cc
+ (diagnostic_manager::emit_saved_diagnostic): Pass NULL for new
+ param to add_events_for_eedge when handling trailing eedge.
+ (diagnostic_manager::build_emission_path): Create an interesting_t
+ instance, allow the pending diagnostic to populate it, and pass it
+ to the calls to add_events_for_eedge.
+ (diagnostic_manager::add_events_for_eedge): Add "interest" param.
+ Use it to add region_creation_events for on-stack regions created
+ within at function entry, and when pertinent dynamically-sized
+ regions are created.
+ (diagnostic_manager::prune_for_sm_diagnostic): Add case for
+ EK_REGION_CREATION.
+ * diagnostic-manager.h (diagnostic_manager::add_events_for_eedge):
+ Add "interest" param.
+ * pending-diagnostic.cc: Include "selftest.h", "tristate.h",
+ "analyzer/call-string.h", "analyzer/program-point.h",
+ "analyzer/store.h", and "analyzer/region-model.h".
+ (interesting_t::add_region_creation): New.
+ (interesting_t::dump_to_pp): New.
+ * pending-diagnostic.h (struct interesting_t): New.
+ (pending_diagnostic::mark_interesting_stuff): New vfunc.
+ * region-model.cc
+ (poisoned_value_diagnostic::poisoned_value_diagnostic): Add
+ (poisoned_value_diagnostic::operator==): Compare m_pkind and
+ m_src_region fields.
+ (poisoned_value_diagnostic::mark_interesting_stuff): New.
+ (poisoned_value_diagnostic::m_src_region): New.
+ (region_model::check_for_poison): Call
+ get_region_for_poisoned_expr for uninit values and pass the resul
+ to the diagnostic.
+ (region_model::get_region_for_poisoned_expr): New.
+ (region_model::deref_rvalue): Pass NULL for
+ poisoned_value_diagnostic's src_region.
+ * region-model.h (region_model::get_region_for_poisoned_expr): New
+ decl.
+ * region.h (frame_region::get_fndecl): New.
+
+2022-01-27 Martin Liska <mliska@suse.cz>
+
+ PR analyzer/104247
+ * constraint-manager.cc (bounded_ranges_manager::log_stats):
+ Cast to long for format purpose.
+ * region-model-manager.cc (log_uniq_map): Likewise.
+
+2022-01-26 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/104224
+ * region-model.cc (region_model::check_call_args): New.
+ (region_model::on_call_pre): Call it when ignoring stdio builtins.
+ * region-model.h (region_model::check_call_args): New decl
+
+2022-01-26 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/94362
+ * constraint-manager.cc (range::add_bound): Fix tests for
+ discarding redundant constraints. Perform test for rejecting
+ unsatisfiable constraints earlier so that they don't update
+ the object on failure.
+ (selftest::test_range): New.
+ (selftest::test_constant_comparisons): Add test coverage for
+ existing constraints becoming narrower until they are
+ unsatisfiable.
+ (selftest::run_constraint_manager_tests): Call test_range.
+
2022-01-22 David Malcolm <dmalcolm@redhat.com>
PR analyzer/104159
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 89f2cad..779ff80 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -81,6 +81,8 @@ event_kind_to_string (enum event_kind ek)
return "EK_CUSTOM";
case EK_STMT:
return "EK_STMT";
+ case EK_REGION_CREATION:
+ return "EK_REGION_CREATION";
case EK_FUNCTION_ENTRY:
return "EK_FUNCTION_ENTRY";
case EK_STATE_CHANGE:
@@ -199,6 +201,34 @@ statement_event::get_desc (bool) const
return label_text::take (xstrdup (pp_formatted_text (&pp)));
}
+/* class region_creation_event : public checker_event. */
+
+region_creation_event::region_creation_event (const region *reg,
+ location_t loc,
+ tree fndecl,
+ int depth)
+: checker_event (EK_REGION_CREATION, loc, fndecl, depth),
+ m_reg (reg)
+{
+}
+
+/* Implementation of diagnostic_event::get_desc vfunc for
+ region_creation_event. */
+
+label_text
+region_creation_event::get_desc (bool) const
+{
+ switch (m_reg->get_memory_space ())
+ {
+ default:
+ return label_text::borrow ("region created here");
+ case MEMSPACE_STACK:
+ return label_text::borrow ("region created on stack here");
+ case MEMSPACE_HEAP:
+ return label_text::borrow ("region created on heap here");
+ }
+}
+
/* class function_entry_event : public checker_event. */
/* Implementation of diagnostic_event::get_desc vfunc for
@@ -991,6 +1021,17 @@ checker_path::debug () const
}
}
+/* Add region_creation_event instance to this path for REG,
+ describing whether REG is on the stack or heap. */
+
+void
+checker_path::add_region_creation_event (const region *reg,
+ location_t loc,
+ tree fndecl, int depth)
+{
+ add_event (new region_creation_event (reg, loc, fndecl, depth));
+}
+
/* Add a warning_event to the end of this path. */
void
diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h
index c7bd39d..d37c999 100644
--- a/gcc/analyzer/checker-path.h
+++ b/gcc/analyzer/checker-path.h
@@ -31,6 +31,7 @@ enum event_kind
EK_DEBUG,
EK_CUSTOM,
EK_STMT,
+ EK_REGION_CREATION,
EK_FUNCTION_ENTRY,
EK_STATE_CHANGE,
EK_START_CFG_EDGE,
@@ -58,6 +59,7 @@ extern const char *event_kind_to_string (enum event_kind ek);
custom_event (EK_CUSTOM)
precanned_custom_event
statement_event (EK_STMT)
+ region_creation_event (EK_REGION_CREATION)
function_entry_event (EK_FUNCTION_ENTRY)
state_change_event (EK_STATE_CHANGE)
superedge_event
@@ -194,6 +196,21 @@ public:
const program_state m_dst_state;
};
+/* A concrete event subclass describing the creation of a region that
+ is significant for a diagnostic e.g. "region created on stack here". */
+
+class region_creation_event : public checker_event
+{
+public:
+ region_creation_event (const region *reg,
+ location_t loc, tree fndecl, int depth);
+
+ label_text get_desc (bool) const FINAL OVERRIDE;
+
+private:
+ const region *m_reg;
+};
+
/* An event subclass describing the entry to a function. */
class function_entry_event : public checker_event
@@ -561,6 +578,10 @@ public:
m_events[idx] = new_event;
}
+ void add_region_creation_event (const region *reg,
+ location_t loc,
+ tree fndecl, int depth);
+
void add_final_event (const state_machine *sm,
const exploded_node *enode, const gimple *stmt,
tree var, state_machine::state_t state);
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 7c4a85b..ac1e4fe 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -318,35 +318,42 @@ range::add_bound (bound b, enum bound_kind bound_kind)
if (m_lower_bound.m_constant)
{
m_lower_bound.ensure_closed (BK_LOWER);
- if (!tree_int_cst_lt (b.m_constant,
- m_lower_bound.m_constant))
+ if (tree_int_cst_le (b.m_constant,
+ m_lower_bound.m_constant))
return true;
}
+ if (m_upper_bound.m_constant)
+ {
+ m_upper_bound.ensure_closed (BK_UPPER);
+ /* Reject B <= V <= UPPER when B > UPPER. */
+ if (!tree_int_cst_le (b.m_constant,
+ m_upper_bound.m_constant))
+ return false;
+ }
m_lower_bound = b;
break;
+
case BK_UPPER:
/* Discard redundant bounds. */
if (m_upper_bound.m_constant)
{
m_upper_bound.ensure_closed (BK_UPPER);
- if (tree_int_cst_le (b.m_constant,
- m_upper_bound.m_constant))
+ if (!tree_int_cst_lt (b.m_constant,
+ m_upper_bound.m_constant))
return true;
}
+ if (m_lower_bound.m_constant)
+ {
+ m_lower_bound.ensure_closed (BK_LOWER);
+ /* Reject LOWER <= V <= B when LOWER > B. */
+ if (!tree_int_cst_le (m_lower_bound.m_constant,
+ b.m_constant))
+ return false;
+ }
m_upper_bound = b;
break;
}
- if (m_lower_bound.m_constant
- && m_upper_bound.m_constant)
- {
- m_lower_bound.ensure_closed (BK_LOWER);
- m_upper_bound.ensure_closed (BK_UPPER);
- /* Reject LOWER <= V <= UPPER when LOWER > UPPER. */
- if (!tree_int_cst_le (m_lower_bound.m_constant,
- m_upper_bound.m_constant))
- return false;
- }
return true;
}
@@ -1024,7 +1031,7 @@ void
bounded_ranges_manager::log_stats (logger *logger, bool show_objs) const
{
LOG_SCOPE (logger);
- logger->log (" # %s: %li", "ranges", m_map.elements ());
+ logger->log (" # %s: %li", "ranges", (long)m_map.elements ());
if (!show_objs)
return;
@@ -3093,6 +3100,49 @@ namespace selftest {
These have to be written in terms of a region_model, since
the latter is responsible for managing svalue instances. */
+/* Verify that range::add_bound works as expected. */
+
+static void
+test_range ()
+{
+ tree int_0 = build_int_cst (integer_type_node, 0);
+ tree int_1 = build_int_cst (integer_type_node, 1);
+ tree int_2 = build_int_cst (integer_type_node, 2);
+ tree int_5 = build_int_cst (integer_type_node, 5);
+
+ {
+ range r;
+ ASSERT_FALSE (r.constrained_to_single_element ());
+
+ /* (r >= 1). */
+ ASSERT_TRUE (r.add_bound (GE_EXPR, int_1));
+
+ /* Redundant. */
+ ASSERT_TRUE (r.add_bound (GE_EXPR, int_0));
+ ASSERT_TRUE (r.add_bound (GT_EXPR, int_0));
+
+ ASSERT_FALSE (r.constrained_to_single_element ());
+
+ /* Contradiction. */
+ ASSERT_FALSE (r.add_bound (LT_EXPR, int_1));
+
+ /* (r < 5). */
+ ASSERT_TRUE (r.add_bound (LT_EXPR, int_5));
+ ASSERT_FALSE (r.constrained_to_single_element ());
+
+ /* Contradiction. */
+ ASSERT_FALSE (r.add_bound (GE_EXPR, int_5));
+
+ /* (r < 2). */
+ ASSERT_TRUE (r.add_bound (LT_EXPR, int_2));
+ ASSERT_TRUE (r.constrained_to_single_element ());
+
+ /* Redundant. */
+ ASSERT_TRUE (r.add_bound (LE_EXPR, int_1));
+ ASSERT_TRUE (r.constrained_to_single_element ());
+ }
+}
+
/* Verify that setting and getting simple conditions within a region_model
work (thus exercising the underlying constraint_manager). */
@@ -3702,6 +3752,20 @@ test_constant_comparisons ()
}
{
region_model model (&mgr);
+ ADD_SAT_CONSTRAINT (model, int_1, LT_EXPR, a);
+ ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
+ ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
+ ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
+ }
+ {
+ region_model model (&mgr);
+ ADD_SAT_CONSTRAINT (model, int_1, LT_EXPR, a);
+ ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
+ ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
+ ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
+ }
+ {
+ region_model model (&mgr);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_4);
ADD_UNSAT_CONSTRAINT (model, int_3, LT_EXPR, a);
}
@@ -4323,6 +4387,7 @@ run_constraint_manager_tests (bool transitivity)
int saved_flag_analyzer_transitivity = flag_analyzer_transitivity;
flag_analyzer_transitivity = transitivity;
+ test_range ();
test_constraint_conditions ();
if (flag_analyzer_transitivity)
{
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 73c133d..80bca6a 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -1222,7 +1222,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
trailing eedge stashed, add any events for it. This is for use
in handling longjmp, to show where a longjmp is rewinding to. */
if (sd.m_trailing_eedge)
- add_events_for_eedge (pb, *sd.m_trailing_eedge, &emission_path);
+ add_events_for_eedge (pb, *sd.m_trailing_eedge, &emission_path, NULL);
emission_path.prepare_for_emission (sd.m_d);
@@ -1269,10 +1269,13 @@ diagnostic_manager::build_emission_path (const path_builder &pb,
checker_path *emission_path) const
{
LOG_SCOPE (get_logger ());
+
+ interesting_t interest;
+ pb.get_pending_diagnostic ()->mark_interesting_stuff (&interest);
for (unsigned i = 0; i < epath.m_edges.length (); i++)
{
const exploded_edge *eedge = epath.m_edges[i];
- add_events_for_eedge (pb, *eedge, emission_path);
+ add_events_for_eedge (pb, *eedge, emission_path, &interest);
}
}
@@ -1580,10 +1583,12 @@ struct null_assignment_sm_context : public sm_context
void
diagnostic_manager::add_events_for_eedge (const path_builder &pb,
const exploded_edge &eedge,
- checker_path *emission_path) const
+ checker_path *emission_path,
+ interesting_t *interest) const
{
const exploded_node *src_node = eedge.m_src;
const program_point &src_point = src_node->get_point ();
+ const int src_stack_depth = src_point.get_stack_depth ();
const exploded_node *dst_node = eedge.m_dest;
const program_point &dst_point = dst_node->get_point ();
const int dst_stack_depth = dst_point.get_stack_depth ();
@@ -1645,6 +1650,29 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
(dst_point.get_supernode ()->get_start_location (),
dst_point.get_fndecl (),
dst_stack_depth));
+ /* Create region_creation_events for on-stack regions within
+ this frame. */
+ if (interest)
+ {
+ unsigned i;
+ const region *reg;
+ FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg)
+ if (const frame_region *frame = reg->maybe_get_frame_region ())
+ if (frame->get_fndecl () == dst_point.get_fndecl ())
+ {
+ const region *base_reg = reg->get_base_region ();
+ if (tree decl = base_reg->maybe_get_decl ())
+ if (DECL_P (decl)
+ && DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
+ {
+ emission_path->add_region_creation_event
+ (reg,
+ DECL_SOURCE_LOCATION (decl),
+ dst_point.get_fndecl (),
+ dst_stack_depth);
+ }
+ }
+ }
}
break;
case PK_BEFORE_STMT:
@@ -1700,6 +1728,42 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb,
== dst_node->m_succs[0]->m_dest->get_point ())))
break;
}
+
+ /* Look for changes in dynamic extents, which will identify
+ the creation of heap-based regions and alloca regions. */
+ if (interest)
+ {
+ const region_model *src_model = src_state.m_region_model;
+ const region_model *dst_model = dst_state.m_region_model;
+ if (src_model->get_dynamic_extents ()
+ != dst_model->get_dynamic_extents ())
+ {
+ unsigned i;
+ const region *reg;
+ FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg)
+ {
+ const region *base_reg = reg->get_base_region ();
+ const svalue *old_extents
+ = src_model->get_dynamic_extents (base_reg);
+ const svalue *new_extents
+ = dst_model->get_dynamic_extents (base_reg);
+ if (old_extents == NULL && new_extents != NULL)
+ switch (base_reg->get_kind ())
+ {
+ default:
+ break;
+ case RK_HEAP_ALLOCATED:
+ case RK_ALLOCA:
+ emission_path->add_region_creation_event
+ (reg,
+ src_point.get_location (),
+ src_point.get_fndecl (),
+ src_stack_depth);
+ break;
+ }
+ }
+ }
+ }
}
}
break;
@@ -2004,6 +2068,10 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
}
break;
+ case EK_REGION_CREATION:
+ /* Don't filter these. */
+ break;
+
case EK_FUNCTION_ENTRY:
if (m_verbosity < 1)
{
diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h
index dd89182..cfc0d86 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -141,7 +141,8 @@ private:
void add_events_for_eedge (const path_builder &pb,
const exploded_edge &eedge,
- checker_path *emission_path) const;
+ checker_path *emission_path,
+ interesting_t *interest) const;
bool significant_edge_p (const path_builder &pb,
const exploded_edge &eedge) const;
diff --git a/gcc/analyzer/pending-diagnostic.cc b/gcc/analyzer/pending-diagnostic.cc
index e35fb61..5e0ea4c 100644
--- a/gcc/analyzer/pending-diagnostic.cc
+++ b/gcc/analyzer/pending-diagnostic.cc
@@ -33,11 +33,43 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-event-id.h"
#include "analyzer/sm.h"
#include "analyzer/pending-diagnostic.h"
+#include "selftest.h"
+#include "tristate.h"
+#include "analyzer/call-string.h"
+#include "analyzer/program-point.h"
+#include "analyzer/store.h"
+#include "analyzer/region-model.h"
#if ENABLE_ANALYZER
namespace ana {
+/* struct interesting_t. */
+
+/* Mark the creation of REG as being interesting. */
+
+void
+interesting_t::add_region_creation (const region *reg)
+{
+ gcc_assert (reg);
+ m_region_creation.safe_push (reg);
+}
+
+void
+interesting_t::dump_to_pp (pretty_printer *pp, bool simple) const
+{
+ pp_string (pp, "{ region creation: [");
+ unsigned i;
+ const region *reg;
+ FOR_EACH_VEC_ELT (m_region_creation, i, reg)
+ {
+ if (i > 0)
+ pp_string (pp, ", ");
+ reg->dump_to_pp (pp, simple);
+ }
+ pp_string (pp, "]}");
+}
+
/* Generate a label_text by printing FMT.
Use a clone of the global_dc for formatting callbacks.
diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h
index 2bc8c1c..5a407c8 100644
--- a/gcc/analyzer/pending-diagnostic.h
+++ b/gcc/analyzer/pending-diagnostic.h
@@ -23,6 +23,22 @@ along with GCC; see the file COPYING3. If not see
namespace ana {
+/* A bundle of information about things that are of interest to a
+ pending_diagnostic.
+
+ For now, merely the set of regions that are pertinent to the
+ diagnostic, so that we can notify the user about when they
+ were created. */
+
+struct interesting_t
+{
+ void add_region_creation (const region *reg);
+
+ void dump_to_pp (pretty_printer *pp, bool simple) const;
+
+ auto_vec<const region *> m_region_creation;
+};
+
/* Various bundles of information used for generating more precise
messages for events within a diagnostic_path, for passing to the
various "describe_*" vfuncs of pending_diagnostic. See those
@@ -282,6 +298,14 @@ class pending_diagnostic
{
return false;
}
+
+ /* Vfunc for registering additional information of interest to this
+ diagnostic. */
+
+ virtual void mark_interesting_stuff (interesting_t *)
+ {
+ /* Default no-op implementation. */
+ }
};
/* A template to make it easier to make subclasses of pending_diagnostic.
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index e765e7f..ba835cb 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -1573,7 +1573,7 @@ static void
log_uniq_map (logger *logger, bool show_objs, const char *title,
const hash_map<K, T*> &uniq_map)
{
- logger->log (" # %s: %li", title, uniq_map.elements ());
+ logger->log (" # %s: %li", title, (long)uniq_map.elements ());
if (!show_objs)
return;
auto_vec<const T *> vec_objs (uniq_map.elements ());
@@ -1597,7 +1597,7 @@ static void
log_uniq_map (logger *logger, bool show_objs, const char *title,
const consolidation_map<T> &map)
{
- logger->log (" # %s: %li", title, map.elements ());
+ logger->log (" # %s: %li", title, (long)map.elements ());
if (!show_objs)
return;
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index f6b7f98..6810cf5 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -454,8 +454,10 @@ class poisoned_value_diagnostic
: public pending_diagnostic_subclass<poisoned_value_diagnostic>
{
public:
- poisoned_value_diagnostic (tree expr, enum poison_kind pkind)
- : m_expr (expr), m_pkind (pkind)
+ poisoned_value_diagnostic (tree expr, enum poison_kind pkind,
+ const region *src_region)
+ : m_expr (expr), m_pkind (pkind),
+ m_src_region (src_region)
{}
const char *get_kind () const FINAL OVERRIDE { return "poisoned_value_diagnostic"; }
@@ -467,7 +469,9 @@ public:
bool operator== (const poisoned_value_diagnostic &other) const
{
- return m_expr == other.m_expr;
+ return (m_expr == other.m_expr
+ && m_pkind == other.m_pkind
+ && m_src_region == other.m_src_region);
}
bool emit (rich_location *rich_loc) FINAL OVERRIDE
@@ -528,9 +532,16 @@ public:
}
}
+ void mark_interesting_stuff (interesting_t *interest) FINAL OVERRIDE
+ {
+ if (m_src_region)
+ interest->add_region_creation (m_src_region);
+ }
+
private:
tree m_expr;
enum poison_kind m_pkind;
+ const region *m_src_region;
};
/* A subclass of pending_diagnostic for complaining about shifts
@@ -839,7 +850,11 @@ region_model::check_for_poison (const svalue *sval,
fixup_tree_for_diagnostic. */
tree diag_arg = fixup_tree_for_diagnostic (expr);
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
- if (ctxt->warn (new poisoned_value_diagnostic (diag_arg, pkind)))
+ const region *src_region = NULL;
+ if (pkind == POISON_KIND_UNINIT)
+ src_region = get_region_for_poisoned_expr (expr);
+ if (ctxt->warn (new poisoned_value_diagnostic (diag_arg, pkind,
+ src_region)))
{
/* We only want to report use of a poisoned value at the first
place it gets used; return an unknown value to avoid generating
@@ -853,6 +868,24 @@ region_model::check_for_poison (const svalue *sval,
return sval;
}
+/* Attempt to get a region for describing EXPR, the source of region of
+ a poisoned_svalue for use in a poisoned_value_diagnostic.
+ Return NULL if there is no good region to use. */
+
+const region *
+region_model::get_region_for_poisoned_expr (tree expr) const
+{
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ tree decl = SSA_NAME_VAR (expr);
+ if (decl && DECL_P (decl))
+ expr = decl;
+ else
+ return NULL;
+ }
+ return get_lvalue (expr, NULL);
+}
+
/* Update this model for the ASSIGN stmt, using CTXT to report any
diagnostics. */
@@ -1044,6 +1077,16 @@ region_model::on_stmt_pre (const gimple *stmt,
}
}
+/* Ensure that all arguments at the call described by CD are checked
+ for poisoned values, by calling get_rvalue on each argument. */
+
+void
+region_model::check_call_args (const call_details &cd) const
+{
+ for (unsigned arg_idx = 0; arg_idx < cd.num_args (); arg_idx++)
+ cd.get_arg_svalue (arg_idx);
+}
+
/* Update this model for the CALL stmt, using CTXT to report any
diagnostics - the first half.
@@ -1173,6 +1216,7 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
/* These stdio builtins have external effects that are out
of scope for the analyzer: we only want to model the effects
on the return value. */
+ check_call_args (cd);
break;
}
else if (is_named_call_p (callee_fndecl, "malloc", call, 1))
@@ -2123,7 +2167,7 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
const poisoned_svalue *poisoned_sval
= as_a <const poisoned_svalue *> (ptr_sval);
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
- ctxt->warn (new poisoned_value_diagnostic (ptr, pkind));
+ ctxt->warn (new poisoned_value_diagnostic (ptr, pkind, NULL));
}
}
}
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index c78efe8..983d082 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -813,6 +813,7 @@ class region_model
const svalue *check_for_poison (const svalue *sval,
tree expr,
region_model_context *ctxt) const;
+ const region * get_region_for_poisoned_expr (tree expr) const;
void check_dynamic_size_for_taint (enum memory_space mem_space,
const svalue *size_in_bytes,
@@ -832,6 +833,8 @@ class region_model
void check_region_for_read (const region *src_reg,
region_model_context *ctxt) const;
+ void check_call_args (const call_details &cd) const;
+
/* Storing this here to avoid passing it around everywhere. */
region_model_manager *const m_mgr;
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index d97bbc1..20eca52 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -298,6 +298,7 @@ public:
/* Accessors. */
const frame_region *get_calling_frame () const { return m_calling_frame; }
function *get_function () const { return m_fun; }
+ tree get_fndecl () const { return get_function ()->decl; }
int get_index () const { return m_index; }
int get_stack_depth () const { return m_index + 1; }
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index bf07341..d784a57 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -119,6 +119,9 @@ static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx);
static rtx expand_builtin_interclass_mathfn (tree, rtx);
static rtx expand_builtin_sincos (tree);
+static rtx expand_builtin_fegetround (tree, rtx, machine_mode);
+static rtx expand_builtin_feclear_feraise_except (tree, rtx, machine_mode,
+ optab);
static rtx expand_builtin_cexpi (tree, rtx);
static rtx expand_builtin_int_roundingfn (tree, rtx);
static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
@@ -2555,6 +2558,62 @@ expand_builtin_sincos (tree exp)
return const0_rtx;
}
+/* Expand call EXP to the fegetround builtin (from C99 fenv.h), returning the
+ result and setting it in TARGET. Otherwise return NULL_RTX on failure. */
+static rtx
+expand_builtin_fegetround (tree exp, rtx target, machine_mode target_mode)
+{
+ if (!validate_arglist (exp, VOID_TYPE))
+ return NULL_RTX;
+
+ insn_code icode = direct_optab_handler (fegetround_optab, SImode);
+ if (icode == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ if (target == 0
+ || GET_MODE (target) != target_mode
+ || !(*insn_data[icode].operand[0].predicate) (target, target_mode))
+ target = gen_reg_rtx (target_mode);
+
+ rtx pat = GEN_FCN (icode) (target);
+ if (!pat)
+ return NULL_RTX;
+ emit_insn (pat);
+
+ return target;
+}
+
+/* Expand call EXP to either feclearexcept or feraiseexcept builtins (from C99
+ fenv.h), returning the result and setting it in TARGET. Otherwise return
+ NULL_RTX on failure. */
+static rtx
+expand_builtin_feclear_feraise_except (tree exp, rtx target,
+ machine_mode target_mode, optab op_optab)
+{
+ if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
+ return NULL_RTX;
+ rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
+
+ insn_code icode = direct_optab_handler (op_optab, SImode);
+ if (icode == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ if (!(*insn_data[icode].operand[1].predicate) (op0, GET_MODE (op0)))
+ return NULL_RTX;
+
+ if (target == 0
+ || GET_MODE (target) != target_mode
+ || !(*insn_data[icode].operand[0].predicate) (target, target_mode))
+ target = gen_reg_rtx (target_mode);
+
+ rtx pat = GEN_FCN (icode) (target, op0);
+ if (!pat)
+ return NULL_RTX;
+ emit_insn (pat);
+
+ return target;
+}
+
/* Expand a call to the internal cexpi builtin to the sincos math function.
EXP is the expression that is a call to the builtin function; if convenient,
the result should be placed in TARGET. */
@@ -7056,6 +7115,26 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
return target;
break;
+ case BUILT_IN_FEGETROUND:
+ target = expand_builtin_fegetround (exp, target, target_mode);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_FECLEAREXCEPT:
+ target = expand_builtin_feclear_feraise_except (exp, target, target_mode,
+ feclearexcept_optab);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_FERAISEEXCEPT:
+ target = expand_builtin_feclear_feraise_except (exp, target, target_mode,
+ feraiseexcept_optab);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_APPLY_ARGS:
return expand_builtin_apply_args ();
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 5595c8d..e3bf1a7 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2022-01-24 Marek Polacek <polacek@redhat.com>
+
+ PR preprocessor/104030
+ * c.opt (Wbidi-chars): Mark as EnumSet. Also accept =ucn.
+
2022-01-21 Jakub Jelinek <jakub@redhat.com>
PR c++/104148
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index db65c14..9cfd2a6 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -379,8 +379,8 @@ C ObjC C++ ObjC++ Warning Alias(Wbidi-chars=,any,none)
;
Wbidi-chars=
-C ObjC C++ ObjC++ RejectNegative Joined Warning CPP(cpp_warn_bidirectional) CppReason(CPP_W_BIDIRECTIONAL) Var(warn_bidirectional) Init(bidirectional_unpaired) Enum(cpp_bidirectional_level)
--Wbidi-chars=[none|unpaired|any] Warn about UTF-8 bidirectional control characters.
+C ObjC C++ ObjC++ RejectNegative Joined Warning CPP(cpp_warn_bidirectional) CppReason(CPP_W_BIDIRECTIONAL) Var(warn_bidirectional) Init(bidirectional_unpaired) Enum(cpp_bidirectional_level) EnumSet
+-Wbidi-chars=[none|unpaired|any|ucn] Warn about UTF-8 bidirectional control characters.
; Required for these enum values.
SourceInclude
@@ -390,13 +390,16 @@ Enum
Name(cpp_bidirectional_level) Type(int) UnknownError(argument %qs to %<-Wbidi-chars%> not recognized)
EnumValue
-Enum(cpp_bidirectional_level) String(none) Value(bidirectional_none)
+Enum(cpp_bidirectional_level) String(none) Value(bidirectional_none) Set(1)
EnumValue
-Enum(cpp_bidirectional_level) String(unpaired) Value(bidirectional_unpaired)
+Enum(cpp_bidirectional_level) String(unpaired) Value(bidirectional_unpaired) Set(1)
EnumValue
-Enum(cpp_bidirectional_level) String(any) Value(bidirectional_any)
+Enum(cpp_bidirectional_level) String(any) Value(bidirectional_any) Set(1)
+
+EnumValue
+Enum(cpp_bidirectional_level) String(ucn) Value(bidirectional_ucn) Set(2)
Wbool-compare
C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
diff --git a/gcc/cfganal.cc b/gcc/cfganal.cc
index e570d27..79c627a 100644
--- a/gcc/cfganal.cc
+++ b/gcc/cfganal.cc
@@ -58,7 +58,7 @@ private:
and heavily borrowed from pre_and_rev_post_order_compute. */
bool
-mark_dfs_back_edges (void)
+mark_dfs_back_edges (struct function *fun)
{
int *pre;
int *post;
@@ -67,20 +67,20 @@ mark_dfs_back_edges (void)
bool found = false;
/* Allocate the preorder and postorder number arrays. */
- pre = XCNEWVEC (int, last_basic_block_for_fn (cfun));
- post = XCNEWVEC (int, last_basic_block_for_fn (cfun));
+ pre = XCNEWVEC (int, last_basic_block_for_fn (fun));
+ post = XCNEWVEC (int, last_basic_block_for_fn (fun));
/* Allocate stack for back-tracking up CFG. */
- auto_vec<edge_iterator, 20> stack (n_basic_blocks_for_fn (cfun) + 1);
+ auto_vec<edge_iterator, 20> stack (n_basic_blocks_for_fn (fun) + 1);
/* Allocate bitmap to track nodes that have been visited. */
- auto_sbitmap visited (last_basic_block_for_fn (cfun));
+ auto_sbitmap visited (last_basic_block_for_fn (fun));
/* None of the nodes in the CFG have been visited yet. */
bitmap_clear (visited);
/* Push the first edge on to the stack. */
- stack.quick_push (ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs));
+ stack.quick_push (ei_start (ENTRY_BLOCK_PTR_FOR_FN (fun)->succs));
while (!stack.is_empty ())
{
@@ -94,8 +94,8 @@ mark_dfs_back_edges (void)
ei_edge (ei)->flags &= ~EDGE_DFS_BACK;
/* Check if the edge destination has been visited yet. */
- if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun) && ! bitmap_bit_p (visited,
- dest->index))
+ if (dest != EXIT_BLOCK_PTR_FOR_FN (fun) && ! bitmap_bit_p (visited,
+ dest->index))
{
/* Mark that we have visited the destination. */
bitmap_set_bit (visited, dest->index);
@@ -112,14 +112,14 @@ mark_dfs_back_edges (void)
}
else
{
- if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
- && src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
+ if (dest != EXIT_BLOCK_PTR_FOR_FN (fun)
+ && src != ENTRY_BLOCK_PTR_FOR_FN (fun)
&& pre[src->index] >= pre[dest->index]
&& post[dest->index] == 0)
ei_edge (ei)->flags |= EDGE_DFS_BACK, found = true;
if (ei_one_before_end_p (ei)
- && src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
+ && src != ENTRY_BLOCK_PTR_FOR_FN (fun))
post[src->index] = postnum++;
if (!ei_one_before_end_p (ei))
@@ -135,6 +135,12 @@ mark_dfs_back_edges (void)
return found;
}
+bool
+mark_dfs_back_edges (void)
+{
+ return mark_dfs_back_edges (cfun);
+}
+
/* Find unreachable blocks. An unreachable block will have 0 in
the reachable bit in block->flags. A nonzero value indicates the
block is reachable. */
diff --git a/gcc/cfganal.h b/gcc/cfganal.h
index 386cfbf..ac637de 100644
--- a/gcc/cfganal.h
+++ b/gcc/cfganal.h
@@ -49,6 +49,7 @@ private:
bitmap_obstack m_bitmaps;
};
+extern bool mark_dfs_back_edges (struct function *);
extern bool mark_dfs_back_edges (void);
extern void find_unreachable_blocks (void);
extern void verify_no_unreachable_blocks (void);
diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
index 9ccc65b..5675751 100644
--- a/gcc/cfgrtl.cc
+++ b/gcc/cfgrtl.cc
@@ -778,6 +778,29 @@ rtl_split_block (basic_block bb, void *insnp)
return new_bb;
}
+/* Return true if LOC1 and LOC2 are equivalent for
+ unique_locus_on_edge_between_p purposes. */
+
+static bool
+loc_equal (location_t loc1, location_t loc2)
+{
+ if (loc1 == loc2)
+ return true;
+
+ expanded_location loce1 = expand_location (loc1);
+ expanded_location loce2 = expand_location (loc2);
+
+ if (loce1.line != loce2.line
+ || loce1.column != loce2.column
+ || loce1.data != loce2.data)
+ return false;
+ if (loce1.file == loce2.file)
+ return true;
+ return (loce1.file != NULL
+ && loce2.file != NULL
+ && filename_cmp (loce1.file, loce2.file) == 0);
+}
+
/* Return true if the single edge between blocks A and B is the only place
in RTL which holds some unique locus. */
@@ -796,7 +819,7 @@ unique_locus_on_edge_between_p (basic_block a, basic_block b)
while (insn != end && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
insn = PREV_INSN (insn);
- if (insn != end && INSN_LOCATION (insn) == goto_locus)
+ if (insn != end && loc_equal (INSN_LOCATION (insn), goto_locus))
return false;
/* Then scan block B forward. */
@@ -808,7 +831,7 @@ unique_locus_on_edge_between_p (basic_block a, basic_block b)
insn = NEXT_INSN (insn);
if (insn != end && INSN_HAS_LOCATION (insn)
- && INSN_LOCATION (insn) == goto_locus)
+ && loc_equal (INSN_LOCATION (insn), goto_locus))
return false;
}
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 0492392..b3c5bce 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -150,6 +150,7 @@
;; mfc transfer from coprocessor
;; const load constant
;; arith integer arithmetic instructions
+;; auipc integer addition to PC
;; logical integer logical instructions
;; shift integer shift instructions
;; slt set less than instructions
@@ -167,6 +168,7 @@
;; multi multiword sequence (or user asm statements)
;; nop no operation
;; ghost an instruction that produces no real code
+;; bitmanip bit manipulation instructions
(define_attr "type"
"unknown,branch,jump,call,load,fpload,store,fpstore,
mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index ad3238b..eb7a0c0 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -23,6 +23,7 @@
#define DEFAULT_ABI ABI_AIX
#undef TARGET_AIX
#define TARGET_AIX 1
+#define OPTION_GLIBC 0
/* Linux64.h wants to redefine TARGET_AIX based on -m64, but it can't be used
in the #if conditional in options-default.h, so provide another macro. */
diff --git a/gcc/config/rs6000/bmi2intrin.h b/gcc/config/rs6000/bmi2intrin.h
index 9bf36e9..f2d7eb5 100644
--- a/gcc/config/rs6000/bmi2intrin.h
+++ b/gcc/config/rs6000/bmi2intrin.h
@@ -29,8 +29,8 @@
standard C or GNU C extensions, which are more portable and better
optimized across multiple targets. */
-#if !defined _X86INTRIN_H_INCLUDED
-# error "Never use <bmi2intrin.h> directly; include <x86intrin.h> instead."
+#if !defined _X86GPRINTRIN_H_INCLUDED
+# error "Never use <bmi2intrin.h> directly; include <x86gprintrin.h> instead."
#endif
#ifndef _BMI2INTRIN_H_INCLUDED
@@ -118,7 +118,8 @@ _pext_u64 (unsigned long long __X, unsigned long long __M)
/* Also if the pext mask is constant, then the popcount is
constant, we can evaluate the following loop at compile
time and use a constant bit permute vector. */
- for (long i = 0; i < __builtin_popcountl (__M); i++)
+ long i;
+ for (i = 0; i < __builtin_popcountl (__M); i++)
{
c = __builtin_clzl (m);
p = (p << 8) | c;
diff --git a/gcc/config/rs6000/bmiintrin.h b/gcc/config/rs6000/bmiintrin.h
index 8845f70..76cbc47 100644
--- a/gcc/config/rs6000/bmiintrin.h
+++ b/gcc/config/rs6000/bmiintrin.h
@@ -29,8 +29,8 @@
standard C or GNU C extensions, which are more portable and better
optimized across multiple targets. */
-#if !defined _X86INTRIN_H_INCLUDED
-# error "Never use <bmiintrin.h> directly; include <x86intrin.h> instead."
+#if !defined _X86GPRINTRIN_H_INCLUDED
+# error "Never use <bmiintrin.h> directly; include <x86gprintrin.h> instead."
#endif
#ifndef _BMIINTRIN_H_INCLUDED
diff --git a/gcc/config/rs6000/emmintrin.h b/gcc/config/rs6000/emmintrin.h
index 6065dc7..71abcca 100644
--- a/gcc/config/rs6000/emmintrin.h
+++ b/gcc/config/rs6000/emmintrin.h
@@ -2215,7 +2215,7 @@ _mm_sad_epu8 (__m128i __A, __m128i __B)
vsum = (__vector signed int) vec_sum4s (vabsdiff, zero);
#ifdef __LITTLE_ENDIAN__
/* Sum across four integers with two integer results. */
- asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero));
+ __asm__ ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero));
/* Note: vec_sum2s could be used here, but on little-endian, vector
shifts are added that are not needed for this use-case.
A vector shift to correctly position the 32-bit integer results
diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index e002e1f..5c870d4 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -755,12 +755,6 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
&& (TYPE_MAIN_VARIANT (return_type)
== long_double_type_node))))
rs6000_passes_long_double = true;
-
- /* Note if we passed or return a IEEE 128-bit type. We changed
- the mangling for these types, and we may need to make an alias
- with the old mangling. */
- if (FLOAT128_IEEE_P (return_mode))
- rs6000_passes_ieee128 = true;
}
if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode))
rs6000_passes_vector = true;
@@ -1179,12 +1173,6 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
|| (type != NULL
&& TYPE_MAIN_VARIANT (type) == long_double_type_node)))
rs6000_passes_long_double = true;
-
- /* Note if we passed or return a IEEE 128-bit type. We changed the
- mangling for these types, and we may need to make an alias with
- the old mangling. */
- if (FLOAT128_IEEE_P (mode))
- rs6000_passes_ieee128 = true;
}
if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
rs6000_passes_vector = true;
diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h
index 2d1090e..8ee8c98 100644
--- a/gcc/config/rs6000/rs6000-internal.h
+++ b/gcc/config/rs6000/rs6000-internal.h
@@ -183,9 +183,6 @@ extern tree rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
tree *args ATTRIBUTE_UNUSED,
bool ignore ATTRIBUTE_UNUSED);
-#if TARGET_ELF
-extern bool rs6000_passes_ieee128;
-#endif
extern bool rs6000_passes_float;
extern bool rs6000_passes_long_double;
extern bool rs6000_passes_vector;
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 943f53e..a5fd36b 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -121,22 +121,9 @@ int dot_symbols;
of this machine mode. */
scalar_int_mode rs6000_pmode;
-#if TARGET_ELF
-/* Note whether IEEE 128-bit floating point was passed or returned, either as
- the __float128/_Float128 explicit type, or when long double is IEEE 128-bit
- floating point. We changed the default C++ mangling for these types and we
- may want to generate a weak alias of the old mangling (U10__float128) to the
- new mangling (u9__ieee128). */
-bool rs6000_passes_ieee128 = false;
-#endif
-
/* Track use of r13 in 64bit AIX TLS. */
static bool xcoff_tls_exec_model_detected = false;
-/* Generate the manged name (i.e. U10__float128) used in GCC 8.1, and not the
- name used in current releases (i.e. u9__ieee128). */
-static bool ieee128_mangling_gcc_8_1;
-
/* Width in bits of a pointer. */
unsigned rs6000_pointer_size;
@@ -1765,11 +1752,6 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_STARTING_FRAME_OFFSET
#define TARGET_STARTING_FRAME_OFFSET rs6000_starting_frame_offset
-#if TARGET_ELF && RS6000_WEAK
-#undef TARGET_ASM_GLOBALIZE_DECL_NAME
-#define TARGET_ASM_GLOBALIZE_DECL_NAME rs6000_globalize_decl_name
-#endif
-
#undef TARGET_SETJMP_PRESERVES_NONVOLATILE_REGS_P
#define TARGET_SETJMP_PRESERVES_NONVOLATILE_REGS_P hook_bool_void_true
@@ -5457,8 +5439,11 @@ rs6000_cost_data::update_target_cost_per_stmt (vect_cost_for_stmt kind,
{
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
unsigned int nunits = vect_nunits_for_cost (vectype);
- /* We don't expect strided/elementwise loads for just 1 nunit. */
- gcc_assert (nunits > 1);
+ /* As PR103702 shows, it's possible that vectorizer wants to do
+ costings for only one unit here, it's no need to do any
+ penalization for it, so simply early return here. */
+ if (nunits == 1)
+ return;
/* i386 port adopts nunits * stmt_cost as the penalized cost
for this kind of penalization, we used to follow it but
found it could result in an unreliable body cost especially
@@ -20262,7 +20247,7 @@ rs6000_mangle_type (const_tree type)
if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IBM_P (TYPE_MODE (type)))
return "g";
if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IEEE_P (TYPE_MODE (type)))
- return ieee128_mangling_gcc_8_1 ? "U10__float128" : "u9__ieee128";
+ return "u9__ieee128";
if (type == vector_pair_type_node)
return "u13__vector_pair";
@@ -28159,39 +28144,6 @@ rs6000_starting_frame_offset (void)
}
-/* Create an alias for a mangled name where we have changed the mangling (in
- GCC 8.1, we used U10__float128, and now we use u9__ieee128). This is called
- via the target hook TARGET_ASM_GLOBALIZE_DECL_NAME. */
-
-#if TARGET_ELF && RS6000_WEAK
-static void
-rs6000_globalize_decl_name (FILE * stream, tree decl)
-{
- const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
-
- targetm.asm_out.globalize_label (stream, name);
-
- if (rs6000_passes_ieee128 && name[0] == '_' && name[1] == 'Z')
- {
- tree save_asm_name = DECL_ASSEMBLER_NAME (decl);
- const char *old_name;
-
- ieee128_mangling_gcc_8_1 = true;
- lang_hooks.set_decl_assembler_name (decl);
- old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- SET_DECL_ASSEMBLER_NAME (decl, save_asm_name);
- ieee128_mangling_gcc_8_1 = false;
-
- if (strcmp (name, old_name) != 0)
- {
- fprintf (stream, "\t.weak %s\n", old_name);
- fprintf (stream, "\t.set %s,%s\n", old_name, name);
- }
- }
-}
-#endif
-
-
/* On 64-bit Linux and Freebsd systems, possibly switch the long double library
function names from <foo>l to <foo>f128 if the default long double type is
IEEE 128-bit. Typically, with the C and C++ languages, the standard math.h
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4e22118..fdfbc65 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -6912,6 +6912,117 @@
[(set_attr "type" "fpload")
(set_attr "length" "8")
(set_attr "isa" "*,p8v,p8v")])
+
+;; int fegetround(void)
+;;
+;; This expansion for the C99 function only expands for compatible
+;; target libcs, because it needs to return one of FE_DOWNWARD,
+;; FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD with the values as defined
+;; by the target libc, and since the libc is free to choose the values
+;; (and they may differ from the hardware) and the expander needs to
+;; know then beforehand, this expanded only expands for target libcs
+;; that it can handle the values is knows.
+;; Because of these restriction, this only expands on the desired
+;; case and fallback to a call to libc otherwise.
+(define_expand "fegetroundsi"
+ [(set (match_operand:SI 0 "gpc_reg_operand")
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_MFFSL))]
+ "TARGET_HARD_FLOAT"
+{
+ if (!OPTION_GLIBC)
+ FAIL;
+
+ rtx tmp_df = gen_reg_rtx (DFmode);
+ emit_insn (gen_rs6000_mffsl (tmp_df));
+
+ rtx tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
+ rtx tmp_di_2 = gen_reg_rtx (DImode);
+ emit_insn (gen_anddi3 (tmp_di_2, tmp_di, GEN_INT (3)));
+ rtx tmp_si = gen_reg_rtx (SImode);
+ tmp_si = gen_lowpart (SImode, tmp_di_2);
+ emit_move_insn (operands[0], tmp_si);
+ DONE;
+})
+
+;; int feclearexcept(int excepts)
+;;
+;; This expansion for the C99 function only works when EXCEPTS is a
+;; constant known at compile time and specifies any one of
+;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
+;; It doesn't handle values out of range, and always returns 0.
+;; Note that FE_INVALID is unsupported because it maps to more than
+;; one bit of the FPSCR register.
+;; The FE_* are defined in the target libc, and since they are free to
+;; choose the values and the expand needs to know them beforehand,
+;; this expander only expands for target libcs that it can handle the
+;; values it knows.
+;; Because of these restrictions, this only expands on the desired
+;; cases and fallback to a call to libc on any other case.
+(define_expand "feclearexceptsi"
+ [(use (match_operand:SI 1 "const_int_operand" "n"))
+ (set (match_operand:SI 0 "gpc_reg_operand")
+ (const_int 0))]
+ "TARGET_HARD_FLOAT"
+{
+ if (!OPTION_GLIBC)
+ FAIL;
+
+ unsigned int fe = INTVAL (operands[1]);
+ if (fe != (fe & 0x1e000000))
+ FAIL;
+
+ if (fe & 0x02000000) /* FE_INEXACT */
+ emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 6)));
+ if (fe & 0x04000000) /* FE_DIVBYZERO */
+ emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 5)));
+ if (fe & 0x08000000) /* FE_UNDERFLOW */
+ emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 4)));
+ if (fe & 0x10000000) /* FE_OVERFLOW */
+ emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 3)));
+
+ emit_move_insn (operands[0], const0_rtx);
+ DONE;
+})
+
+;; int feraiseexcept(int excepts)
+;;
+;; This expansion for the C99 function only works when excepts is a
+;; constant known at compile time and specifies any one of
+;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
+;; It doesn't handle values out of range, and always returns 0.
+;; Note that FE_INVALID is unsupported because it maps to more than
+;; one bit of the FPSCR register.
+;; The FE_* are defined in the target libc, and since they are free to
+;; choose the values and the expand needs to know them beforehand,
+;; this expander only expands for target libcs that it can handle the
+;; values it knows.
+;; Because of these restrictions, this only expands on the desired
+;; cases and fallback to a call to libc on any other case.
+(define_expand "feraiseexceptsi"
+ [(use (match_operand:SI 1 "const_int_operand" "n"))
+ (set (match_operand:SI 0 "gpc_reg_operand")
+ (const_int 0))]
+ "TARGET_HARD_FLOAT"
+{
+ if (!OPTION_GLIBC)
+ FAIL;
+
+ unsigned int fe = INTVAL (operands[1]);
+ if (fe != (fe & 0x1e000000))
+ FAIL;
+
+ if (fe & 0x02000000) /* FE_INEXACT */
+ emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 6)));
+ if (fe & 0x04000000) /* FE_DIVBYZERO */
+ emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 5)));
+ if (fe & 0x08000000) /* FE_UNDERFLOW */
+ emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 4)));
+ if (fe & 0x10000000) /* FE_OVERFLOW */
+ emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 3)));
+
+ emit_move_insn (operands[0], const0_rtx);
+ DONE;
+})
;; Define the TImode operations that can be done in a small number
;; of instructions. The & constraints are to prevent the register
diff --git a/gcc/config/rs6000/smmintrin.h b/gcc/config/rs6000/smmintrin.h
index 4f90c2e..cca2f7d 100644
--- a/gcc/config/rs6000/smmintrin.h
+++ b/gcc/config/rs6000/smmintrin.h
@@ -687,7 +687,8 @@ _mm_minpos_epu16 (__m128i __A)
union __u __u = { .__m = __A }, __r = { .__m = {0} };
unsigned short __ridx = 0;
unsigned short __rmin = __u.__uh[__ridx];
- for (unsigned long __i = 1; __i < 8; __i++)
+ unsigned long __i;
+ for (__i = 1; __i < 8; __i++)
{
if (__u.__uh[__i] < __rmin)
{
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1aadfa9..4301b5c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,93 @@
+2022-01-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/104245
+ PR c++/51344
+ * decl2.cc (save_template_attributes): Take late attrs as parm.
+ (cplus_decl_attributes): Call it after decl_attributes,
+ splice_template_attributes before.
+
+2022-01-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/99895
+ * call.cc (build_over_call): For a non-dependent member call,
+ build up a CALL_EXPR using a COMPONENT_REF callee, as in
+ build_new_method_call.
+ * pt.cc (build_non_dependent_expr): Don't wrap PARM_DECL either.
+ * tree.cc (build_min_non_dep_op_overload): Adjust accordingly
+ after the build_over_call change.
+
+2022-01-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/92944
+ PR c++/103678
+ * parser.cc (cp_parser_class_head): Update 'type' with the result
+ of maybe_process_partial_specialization in the
+ nested_name_specifier branch. Refactor nearby code to accomodate
+ that maybe_process_partial_specialization returns a _TYPE, not a
+ TYPE_DECL, and eliminate local variable 'class_type' in passing.
+
+2022-01-27 Marek Polacek <polacek@redhat.com>
+
+ PR c++/101988
+ * decl.cc (create_array_type_for_decl): Reject forming an array of
+ placeholder for a deduced class type.
+
+2022-01-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/104206
+ PR c++/101072
+ * semantics.cc (finish_compound_literal): Restore VECTOR_TYPE check.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/104226
+ * constexpr.cc (init_subob_ctx): For vector ctors containing
+ vector elements, ensure appending to the same ctor instead of
+ creating another one.
+
+2022-01-26 Marek Polacek <polacek@redhat.com>
+
+ PR target/104213
+ * decl.cc (finish_constructor_body): Suppress -Wuse-after-free.
+ (finish_destructor_body): Likewise.
+ * optimize.cc (build_delete_destructor_body): Likewise.
+
+2022-01-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/104235
+ * parser.cc (cp_parser_template_name): Repeat lookup of USING_DECL.
+
+2022-01-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/103057
+ * pt.cc (tsubst_aggr_type): Call tsubst for alias template
+ specialization.
+
+2022-01-25 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101532
+ PR c++/104225
+ * decl2.cc (mark_used): Don't consider maybe_instantiate_noexcept
+ on a deleted function.
+
+2022-01-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/59950
+ * call.cc (build_over_call): Use cp_build_indirect_ref.
+
+2022-01-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/104197
+ * pt.cc (make_auto_1): Use -1 as a placeholder default argument
+ for level.
+
+2022-01-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/104173
+ * typeck.cc (build_class_member_access_expr): Extend
+ unary_complex_lvalue result adjustment to preserve all
+ rvalues, not just xvalues.
+
2022-01-23 Will Wray <wjwray@gmail.com>
PR c++/55227
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index f7f861c..b2e89c5 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9204,11 +9204,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
errors will be deferred until the template is instantiated. */
if (processing_template_decl)
{
- tree expr, addr;
- tree return_type;
- const tree *argarray;
- unsigned int nargs;
-
if (undeduced_auto_decl (fn))
mark_used (fn, complain);
else
@@ -9216,32 +9211,27 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
See PR80598. */
TREE_USED (fn) = 1;
- return_type = TREE_TYPE (TREE_TYPE (fn));
- nargs = vec_safe_length (args);
+ tree return_type = TREE_TYPE (TREE_TYPE (fn));
+ tree callee;
if (first_arg == NULL_TREE)
- argarray = args->address ();
+ {
+ callee = build_addr_func (fn, complain);
+ if (callee == error_mark_node)
+ return error_mark_node;
+ }
else
{
- tree *alcarray;
- unsigned int ix;
- tree arg;
-
- ++nargs;
- alcarray = XALLOCAVEC (tree, nargs);
- alcarray[0] = build_this (first_arg);
- FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
- alcarray[ix + 1] = arg;
- argarray = alcarray;
+ tree binfo = TYPE_BINFO (TREE_TYPE (first_arg));
+ callee = build_baselink (binfo, binfo, fn, NULL_TREE);
+ callee = build_min (COMPONENT_REF, TREE_TYPE (fn),
+ first_arg, callee, NULL_TREE);
}
- addr = build_addr_func (fn, complain);
- if (addr == error_mark_node)
- return error_mark_node;
- expr = build_call_array_loc (input_location, return_type,
- addr, nargs, argarray);
+ tree expr = build_call_vec (return_type, callee, args);
+ SET_EXPR_LOCATION (expr, input_location);
if (TREE_THIS_VOLATILE (fn) && cfun)
current_function_returns_abnormally = 1;
- if (immediate_invocation_p (fn, nargs))
+ if (immediate_invocation_p (fn, vec_safe_length (args)))
{
tree obj_arg = NULL_TREE, exprimm = expr;
if (DECL_CONSTRUCTOR_P (fn))
@@ -9789,7 +9779,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
&& DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR)
&& trivial_fn_p (fn))
{
- tree to = cp_build_fold_indirect_ref (argarray[0]);
+ /* Don't use cp_build_fold_indirect_ref, op= returns an lvalue even if
+ the object argument isn't one. */
+ tree to = cp_build_indirect_ref (input_location, argarray[0],
+ RO_ARROW, complain);
tree type = TREE_TYPE (to);
tree as_base = CLASSTYPE_AS_BASE (type);
tree arg = argarray[1];
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index dcc1674..7f44253 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -4658,6 +4658,13 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
/* A non-aggregate member doesn't get its own CONSTRUCTOR. */
return;
+ if (VECTOR_TYPE_P (type)
+ && VECTOR_TYPE_P (TREE_TYPE (ctx->ctor))
+ && index == NULL_TREE)
+ /* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
+ vector is constructed from smaller vectors, doesn't get its own
+ CONSTRUCTOR either. */
+ return;
/* The sub-aggregate initializer might contain a placeholder;
update object to refer to the subobject and ctor to refer to
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 22d3dd1..10e6956 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -11087,6 +11087,18 @@ create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
if (type == error_mark_node || size == error_mark_node)
return error_mark_node;
+ /* [dcl.type.class.deduct] prohibits forming an array of placeholder
+ for a deduced class type. */
+ if (is_auto (type) && CLASS_PLACEHOLDER_TEMPLATE (type))
+ {
+ if (name)
+ error_at (loc, "%qD declared as array of template placeholder "
+ "type %qT", name, type);
+ else
+ error ("creating array of template placeholder type %qT", type);
+ return error_mark_node;
+ }
+
/* If there are some types which cannot be array elements,
issue an error-message and return. */
switch (TREE_CODE (type))
@@ -17315,6 +17327,7 @@ finish_constructor_body (void)
add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
val = DECL_ARGUMENTS (current_function_decl);
+ suppress_warning (val, OPT_Wuse_after_free);
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (current_function_decl), val);
/* Return the address of the object. */
@@ -17408,6 +17421,7 @@ finish_destructor_body (void)
tree val;
val = DECL_ARGUMENTS (current_function_decl);
+ suppress_warning (val, OPT_Wuse_after_free);
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (current_function_decl), val);
/* Return the address of the object. */
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 69b9744..a2aa5f1 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -1352,18 +1352,14 @@ splice_template_attributes (tree *attr_p, tree decl)
return late_attrs;
}
-/* Remove any late attributes from the list in ATTR_P and attach them to
- DECL_P. */
+/* Attach any LATE_ATTRS to DECL_P, after the non-dependent attributes have
+ been applied by a previous call to decl_attributes. */
static void
-save_template_attributes (tree *attr_p, tree *decl_p, int flags)
+save_template_attributes (tree late_attrs, tree *decl_p, int flags)
{
tree *q;
- if (attr_p && *attr_p == error_mark_node)
- return;
-
- tree late_attrs = splice_template_attributes (attr_p, *decl_p);
if (!late_attrs)
return;
@@ -1666,12 +1662,12 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
}
}
+ tree late_attrs = NULL_TREE;
if (processing_template_decl)
{
if (check_for_bare_parameter_packs (attributes))
return;
-
- save_template_attributes (&attributes, decl, flags);
+ late_attrs = splice_template_attributes (&attributes, *decl);
}
cp_check_const_attributes (attributes);
@@ -1717,6 +1713,9 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
decl_attributes (decl, attributes, flags, last_decl);
}
+ if (late_attrs)
+ save_template_attributes (late_attrs, decl, flags);
+
/* Propagate deprecation out to the template. */
if (TREE_DEPRECATED (*decl))
if (tree ti = get_template_info (*decl))
@@ -5774,6 +5773,7 @@ mark_used (tree decl, tsubst_flags_t complain)
used_types_insert (DECL_CONTEXT (decl));
if (TREE_CODE (decl) == FUNCTION_DECL
+ && !DECL_DELETED_FN (decl)
&& !maybe_instantiate_noexcept (decl, complain))
return false;
diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc
index 4ad3f1d..13ab8b7 100644
--- a/gcc/cp/optimize.cc
+++ b/gcc/cp/optimize.cc
@@ -166,6 +166,7 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
if (targetm.cxx.cdtor_returns_this ())
{
tree val = DECL_ARGUMENTS (delete_dtor);
+ suppress_warning (val, OPT_Wuse_after_free);
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (delete_dtor), val);
add_stmt (build_stmt (0, RETURN_EXPR, val));
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index ed219d7..94a5c64 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -18680,7 +18680,8 @@ cp_parser_template_name (cp_parser* parser,
cp_parser_error (parser, "expected template-name");
return error_mark_node;
}
- else if (!DECL_P (decl) && !is_overloaded_fn (decl))
+ else if ((!DECL_P (decl) && !is_overloaded_fn (decl))
+ || TREE_CODE (decl) == USING_DECL)
/* Repeat the lookup at instantiation time. */
decl = identifier;
}
@@ -21145,7 +21146,16 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
/* If we are processing a template, make sure the initializer of the
enumerator doesn't contain any bare template parameter pack. */
- if (check_for_bare_parameter_packs (value))
+ if (current_lambda_expr ())
+ {
+ /* In a lambda it should work, but doesn't currently. */
+ if (uses_parameter_packs (value))
+ {
+ sorry ("unexpanded parameter pack in enumerator in lambda");
+ value = error_mark_node;
+ }
+ }
+ else if (check_for_bare_parameter_packs (value))
value = error_mark_node;
/* Create the enumerator. */
@@ -26534,7 +26544,7 @@ cp_parser_class_head (cp_parser* parser,
}
else if (nested_name_specifier)
{
- tree class_type;
+ type = TREE_TYPE (type);
/* Given:
@@ -26544,31 +26554,27 @@ cp_parser_class_head (cp_parser* parser,
we will get a TYPENAME_TYPE when processing the definition of
`S::T'. We need to resolve it to the actual type before we
try to define it. */
- if (TREE_CODE (TREE_TYPE (type)) == TYPENAME_TYPE)
+ if (TREE_CODE (type) == TYPENAME_TYPE)
{
- class_type = resolve_typename_type (TREE_TYPE (type),
- /*only_current_p=*/false);
- if (TREE_CODE (class_type) != TYPENAME_TYPE)
- type = TYPE_NAME (class_type);
- else
+ type = resolve_typename_type (type, /*only_current_p=*/false);
+ if (TREE_CODE (type) == TYPENAME_TYPE)
{
cp_parser_error (parser, "could not resolve typename type");
type = error_mark_node;
}
}
- if (maybe_process_partial_specialization (TREE_TYPE (type))
- == error_mark_node)
+ type = maybe_process_partial_specialization (type);
+ if (type == error_mark_node)
{
type = NULL_TREE;
goto done;
}
- class_type = current_class_type;
/* Enter the scope indicated by the nested-name-specifier. */
pushed_scope = push_scope (nested_name_specifier);
/* Get the canonical version of this type. */
- type = TYPE_MAIN_DECL (TREE_TYPE (type));
+ type = TYPE_MAIN_DECL (type);
/* Call push_template_decl if it seems like we should be defining a
template either from the template headers or the type we're
defining, so that we diagnose both extra and missing headers. */
@@ -26627,6 +26633,14 @@ cp_parser_class_head (cp_parser* parser,
if (type)
{
+ if (current_lambda_expr ()
+ && uses_parameter_packs (attributes))
+ {
+ /* In a lambda this should work, but doesn't currently. */
+ sorry ("unexpanded parameter pack in local class in lambda");
+ attributes = NULL_TREE;
+ }
+
/* Apply attributes now, before any use of the class as a template
argument in its base list. */
cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index bba62a5..f46a7ad 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4273,10 +4273,27 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */)
cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
delete ppd.visited;
+ if (!parameter_packs)
+ return false;
+
+ if (loc == UNKNOWN_LOCATION)
+ loc = cp_expr_loc_or_input_loc (t);
+
/* It's OK for a lambda to have an unexpanded parameter pack from the
containing context, but do complain about unexpanded capture packs. */
- if (current_class_type && LAMBDA_TYPE_P (current_class_type)
- && CLASSTYPE_TEMPLATE_INFO (current_class_type))
+ tree lam = current_lambda_expr ();
+ if (lam)
+ lam = TREE_TYPE (lam);
+
+ if (lam && lam != current_class_type)
+ {
+ /* We're in a lambda, but it isn't the innermost class.
+ This should work, but currently doesn't. */
+ sorry_at (loc, "unexpanded parameter pack in local class in lambda");
+ return true;
+ }
+
+ if (lam && CLASSTYPE_TEMPLATE_INFO (lam))
for (; parameter_packs;
parameter_packs = TREE_CHAIN (parameter_packs))
{
@@ -4287,8 +4304,6 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */)
if (parameter_packs)
{
- if (loc == UNKNOWN_LOCATION)
- loc = cp_expr_loc_or_input_loc (t);
error_at (loc, "parameter packs not expanded with %<...%>:");
while (parameter_packs)
{
@@ -13585,6 +13600,14 @@ tsubst_aggr_type (tree t,
if (t == NULL_TREE)
return NULL_TREE;
+ /* If T is an alias template specialization, we want to substitute that
+ rather than strip it, especially if it's dependent_alias_template_spec_p.
+ It should be OK not to handle entering_scope in this case, since
+ DECL_CONTEXT will never be an alias template specialization. We only get
+ here with an alias when tsubst calls us for TYPENAME_TYPE. */
+ if (alias_template_specialization_p (t, nt_transparent))
+ return tsubst (t, args, complain, in_decl);
+
switch (TREE_CODE (t))
{
case RECORD_TYPE:
@@ -28402,8 +28425,10 @@ build_non_dependent_expr (tree expr)
if (is_overloaded_fn (inner_expr)
|| TREE_CODE (inner_expr) == OFFSET_REF)
return orig_expr;
- /* There is no need to return a proxy for a variable or enumerator. */
- if (VAR_P (expr) || TREE_CODE (expr) == CONST_DECL)
+ /* There is no need to return a proxy for a variable, parameter
+ or enumerator. */
+ if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL
+ || TREE_CODE (expr) == CONST_DECL)
return orig_expr;
/* Preserve string constants; conversions from string constants to
"char *" are allowed, even though normally a "const char *"
@@ -28477,9 +28502,10 @@ make_args_non_dependent (vec<tree, va_gc> *args)
by default. If set_canonical is true, we set TYPE_CANONICAL on it. */
static tree
-make_auto_1 (tree name, bool set_canonical,
- int level = current_template_depth + 1)
+make_auto_1 (tree name, bool set_canonical, int level = -1)
{
+ if (level == -1)
+ level = current_template_depth + 1;
tree au = cxx_make_type (TEMPLATE_TYPE_PARM);
TYPE_NAME (au) = build_decl (input_location, TYPE_DECL, name, au);
TYPE_STUB_DECL (au) = TYPE_NAME (au);
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 07c2b33..466d6b5 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -3272,8 +3272,9 @@ finish_compound_literal (tree type, tree compound_literal,
/* Represent other compound literals with TARGET_EXPR so we produce
a prvalue, and can elide copies. */
- if (TREE_CODE (compound_literal) == CONSTRUCTOR
- || TREE_CODE (compound_literal) == VEC_INIT_EXPR)
+ if (!VECTOR_TYPE_P (type)
+ && (TREE_CODE (compound_literal) == CONSTRUCTOR
+ || TREE_CODE (compound_literal) == VEC_INIT_EXPR))
{
/* The CONSTRUCTOR is now an initializer, not a compound literal. */
if (TREE_CODE (compound_literal) == CONSTRUCTOR)
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 5d453e4..056f10f 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3661,6 +3661,8 @@ build_min_non_dep_op_overload (enum tree_code op,
nargs = call_expr_nargs (non_dep);
expected_nargs = cp_tree_code_length (op);
+ if (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE)
+ expected_nargs -= 1;
if ((op == POSTINCREMENT_EXPR
|| op == POSTDECREMENT_EXPR)
/* With -fpermissive non_dep could be operator++(). */
@@ -3687,7 +3689,7 @@ build_min_non_dep_op_overload (enum tree_code op,
tree method = build_baselink (binfo, binfo, overload, NULL_TREE);
fn = build_min (COMPONENT_REF, TREE_TYPE (overload),
object, method, NULL_TREE);
- for (int i = 1; i < nargs; i++)
+ for (int i = 0; i < nargs; i++)
{
tree arg = va_arg (p, tree);
vec_safe_push (args, arg);
@@ -3723,7 +3725,6 @@ build_min_non_dep_op_overload (tree non_dep, tree overload, tree object,
tree method = build_baselink (binfo, binfo, overload, NULL_TREE);
tree fn = build_min (COMPONENT_REF, TREE_TYPE (overload),
object, method, NULL_TREE);
- nargs--;
gcc_assert (vec_safe_length (args) == nargs);
tree call = build_min_non_dep_call_vec (non_dep, fn, args);
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 3a28d63..11c9d8a 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -2726,17 +2726,14 @@ build_class_member_access_expr (cp_expr object, tree member,
/* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
`(*(a ? &b : &c)).x', and so on. A COND_EXPR is only an lvalue
in the front end; only _DECLs and _REFs are lvalues in the back end. */
- {
- tree temp = unary_complex_lvalue (ADDR_EXPR, object);
- if (temp)
- {
- temp = cp_build_fold_indirect_ref (temp);
- if (xvalue_p (object) && !xvalue_p (temp))
- /* Preserve xvalue kind. */
- temp = move (temp);
- object = temp;
- }
- }
+ if (tree temp = unary_complex_lvalue (ADDR_EXPR, object))
+ {
+ temp = cp_build_fold_indirect_ref (temp);
+ if (!lvalue_p (object) && lvalue_p (temp))
+ /* Preserve rvalueness. */
+ temp = move (temp);
+ object = temp;
+ }
/* In [expr.ref], there is an explicit list of the valid choices for
MEMBER. We check for each of those cases here. */
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index f5f43d5..1047204 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -219,6 +219,8 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
context->show_line_numbers_p = false;
context->min_margin_width = 0;
context->show_ruler_p = false;
+ context->report_bug = false;
+
if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
{
if (!strcmp (var, "fixits-v1"))
@@ -665,12 +667,16 @@ diagnostic_action_after_output (diagnostic_context *context,
if (context->abort_on_error)
real_abort ();
- fnotice (stderr, "Please submit a full bug report,\n"
- "with preprocessed source if appropriate.\n");
+ if (context->report_bug)
+ fnotice (stderr, "\nPlease submit a full bug report, "
+ "with preprocessed source.\n");
+ else
+ fnotice (stderr, "\nPlease submit a full bug report, "
+ "with preprocessed source (by using -freport-bug).\n");
+
if (count > 0)
- fnotice (stderr,
- ("Please include the complete backtrace "
- "with any bug report.\n"));
+ fnotice (stderr, "Please include the complete backtrace "
+ "with any bug report.\n");
fnotice (stderr, "See %s for instructions.\n", bug_report_url);
exit (ICE_EXIT_CODE);
@@ -1437,8 +1443,8 @@ num_digits (int value)
/* Given a partial pathname as input, return another pathname that
shares no directory elements with the pathname of __FILE__. This
- is used by fancy_abort() to print `Internal compiler error in expr.cc'
- instead of `Internal compiler error in ../../GCC/gcc/expr.cc'. */
+ is used by fancy_abort() to print `internal compiler error in expr.cc'
+ instead of `internal compiler error in ../../GCC/gcc/expr.cc'. */
const char *
trim_filename (const char *name)
@@ -1988,7 +1994,7 @@ error_recursion (diagnostic_context *context)
pp_newline_and_flush (context->printer);
fnotice (stderr,
- "Internal compiler error: Error reporting routines re-entered.\n");
+ "internal compiler error: error reporting routines re-entered.\n");
/* Call diagnostic_action_after_output to get the "please submit a bug
report" message. */
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index ccaa33b..3ca3297 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -340,6 +340,9 @@ struct diagnostic_context
source output. */
bool show_ruler_p;
+ /* True if -freport-bug option is used. */
+ bool report_bug;
+
/* Used to specify additional diagnostic output to be emitted after the
rest of the diagnostic. This is for implementing
-fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index bbde66c..854e297 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13501,6 +13501,14 @@ In the same fashion, GCC provides @code{fpclassify}, @code{isfinite},
@code{__builtin_} prefixed. The @code{isinf} and @code{isnan}
built-in functions appear both with and without the @code{__builtin_} prefix.
+GCC provides built-in versions of the ISO C99 floating-point rounding and
+exceptions handling functions @code{fegetround}, @code{feclearexcept} and
+@code{feraiseexcept}. They may not be available for all targets, and because
+they need close interaction with libc internal values, they may not be available
+for all target libcs, but in all cases they will gracefully fallback to libc
+calls. This built-in functions appear both with and without the
+@code{__builtin_} prefix.
+
@deftypefn {Built-in Function} void *__builtin_alloca (size_t size)
The @code{__builtin_alloca} function must be called at block scope.
The function allocates an object @var{size} bytes large on the stack
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ce3d78d..817c940 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -291,7 +291,7 @@ Objective-C and Objective-C++ Dialects}.
-Warray-bounds -Warray-bounds=@var{n} -Warray-compare @gol
-Wno-attributes -Wattribute-alias=@var{n} -Wno-attribute-alias @gol
-Wno-attribute-warning @gol
--Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} @gol
+-Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{|}ucn@r{]} @gol
-Wbool-compare -Wbool-operation @gol
-Wno-builtin-declaration-mismatch @gol
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol
@@ -7766,7 +7766,7 @@ Attributes considered include @code{alloc_align}, @code{alloc_size},
This is the default. You can disable these warnings with either
@option{-Wno-attribute-alias} or @option{-Wattribute-alias=0}.
-@item -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]}
+@item -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{|}ucn@r{]}
@opindex Wbidi-chars=
@opindex Wbidi-chars
@opindex Wno-bidi-chars
@@ -7783,6 +7783,10 @@ bidi contexts. @option{-Wbidi-chars=none} turns the warning off.
@option{-Wbidi-chars=any} warns about any use of bidirectional control
characters.
+By default, this warning does not warn about UCNs. It is, however, possible
+to turn on such checking by using @option{-Wbidi-chars=unpaired,ucn} or
+@option{-Wbidi-chars=any,ucn}.
+
@item -Wbool-compare
@opindex Wno-bool-compare
@opindex Wbool-compare
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 7f0aab9..feacb12 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -6087,6 +6087,23 @@ mode @var{m}, which is a scalar or vector floating-point mode.
This pattern is not allowed to @code{FAIL}.
+@cindex @code{fegetround@var{m}} instruction pattern
+@item @samp{fegetround@var{m}}
+Store the current machine floating-point rounding mode into operand 0.
+Operand 0 has mode @var{m}, which is scalar. This pattern is used to
+implement the @code{fegetround} function from the ISO C99 standard.
+
+@cindex @code{feclearexcept@var{m}} instruction pattern
+@cindex @code{feraiseexcept@var{m}} instruction pattern
+@item @samp{feclearexcept@var{m}}
+@item @samp{feraiseexcept@var{m}}
+Clears or raises the supported machine floating-point exceptions
+represented by the bits in operand 1. Error status is stored as
+nonzero value in operand 0. Both operands have mode @var{m}, which is
+a scalar. These patterns are used to implement the
+@code{feclearexcept} and @code{feraiseexcept} functions from the ISO
+C99 standard.
+
@cindex @code{exp@var{m}2} instruction pattern
@item @samp{exp@var{m}2}
Raise e (the base of natural logarithms) to the power of operand 1
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index a5a7f63..ad1d804 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -13568,6 +13568,47 @@ qualified_die_p (dw_die_ref die, int *mask, unsigned int depth)
return type;
}
+/* If TYPE is long double or complex long double that
+ should be emitted as artificial typedef to _Float128 or
+ complex _Float128, return the type it should be emitted as.
+ This is done in case the target already supports 16-byte
+ composite floating point type (ibm_extended_format). */
+
+static tree
+long_double_as_float128 (tree type)
+{
+ if (type != long_double_type_node
+ && type != complex_long_double_type_node)
+ return NULL_TREE;
+
+ machine_mode mode, fmode;
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ mode = TYPE_MODE (TREE_TYPE (type));
+ else
+ mode = TYPE_MODE (type);
+ if (known_eq (GET_MODE_SIZE (mode), 16) && !MODE_COMPOSITE_P (mode))
+ FOR_EACH_MODE_IN_CLASS (fmode, MODE_FLOAT)
+ if (known_eq (GET_MODE_SIZE (fmode), 16)
+ && MODE_COMPOSITE_P (fmode))
+ {
+ if (type == long_double_type_node)
+ {
+ if (float128_type_node
+ && (TYPE_MODE (float128_type_node)
+ == TYPE_MODE (type)))
+ return float128_type_node;
+ return NULL_TREE;
+ }
+ for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+ if (COMPLEX_FLOATN_NX_TYPE_NODE (i) != NULL_TREE
+ && (TYPE_MODE (COMPLEX_FLOATN_NX_TYPE_NODE (i))
+ == TYPE_MODE (type)))
+ return COMPLEX_FLOATN_NX_TYPE_NODE (i);
+ }
+
+ return NULL_TREE;
+}
+
/* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
entry that chains the modifiers specified by CV_QUALS in front of the
given type. REVERSE is true if the type is to be interpreted in the
@@ -13848,7 +13889,32 @@ modified_type_die (tree type, int cv_quals, bool reverse,
}
else if (is_base_type (type))
{
- mod_type_die = base_type_die (type, reverse);
+ /* If a target supports long double as different floating point
+ modes with the same 16-byte size, use normal DW_TAG_base_type
+ only for the composite (ibm_extended_real_format) type and
+ for the other for the time being emit instead a "_Float128"
+ or "complex _Float128" DW_TAG_base_type and a "long double"
+ or "complex long double" typedef to it. */
+ if (tree other_type = long_double_as_float128 (type))
+ {
+ dw_die_ref other_die;
+ if (TYPE_NAME (other_type))
+ other_die
+ = modified_type_die (other_type, TYPE_UNQUALIFIED, reverse,
+ context_die);
+ else
+ {
+ other_die = base_type_die (type, reverse);
+ add_child_die (comp_unit_die (), other_die);
+ add_name_attribute (other_die,
+ TREE_CODE (type) == COMPLEX_TYPE
+ ? "complex _Float128" : "_Float128");
+ }
+ mod_type_die = new_die_raw (DW_TAG_typedef);
+ add_AT_die_ref (mod_type_die, DW_AT_type, other_die);
+ }
+ else
+ mod_type_die = base_type_die (type, reverse);
/* The DIE with DW_AT_endianity is placed right after the naked DIE. */
if (reverse_base_type)
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index ea90c19..877f345 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,44 @@
+2022-01-27 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104128
+ * expr.cc (gfc_copy_expr): Convert internal representation of
+ string to wide char in value only for default character kind.
+ * target-memory.cc (interpret_array): Pass flag for conversion of
+ wide chars.
+ (gfc_target_interpret_expr): Likewise.
+
+2022-01-27 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/84784
+ * trans-intrinsic.cc (conv_intrinsic_image_status): Convert result
+ to resulting (default) integer type.
+ (conv_intrinsic_team_number): Likewise.
+ (gfc_conv_intrinsic_popcnt_poppar): Likewise.
+
+2022-01-25 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104227
+ * check.cc (gfc_calculate_transfer_sizes): Fix checking of arrays
+ passed as MOLD argument to the TRANSFER intrinsic for having
+ storage size zero.
+
+2022-01-25 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104212
+ * check.cc (gfc_check_norm2): Check that optional argument DIM is
+ scalar.
+ (gfc_check_parity): Likewise.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ * lang.opt (fconvert=): Add EnumSet property and mention also
+ r16_ieee and r16_ibm arguments.
+ (big-endian, little-endian, native, swap): Add Set(1) property.
+ (r16_ieee, r16_ibm): New EnumValue entries with Set(2) property.
+ * trans-types.cc (gfc_init_kinds): Emit gfc_fatal_error for
+ -fconvert=r16_ieee or -fconvert=r16_ibm when R16_IEEE <=> R16_IBM
+ conversions aren't supported.
+
2022-01-22 Harald Anlauf <anlauf@gmx.de>
PR fortran/104127
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 5fe8d45..d6c6767 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -4338,6 +4338,9 @@ gfc_check_norm2 (gfc_expr *array, gfc_expr *dim)
if (!array_check (array, 0))
return false;
+ if (!dim_check (dim, 1, false))
+ return false;
+
if (!dim_rank_check (dim, array, false))
return false;
@@ -4476,6 +4479,9 @@ gfc_check_parity (gfc_expr *mask, gfc_expr *dim)
if (!array_check (mask, 0))
return false;
+ if (!dim_check (dim, 1, false))
+ return false;
+
if (!dim_rank_check (dim, mask, false))
return false;
@@ -6145,7 +6151,7 @@ gfc_calculate_transfer_sizes (gfc_expr *source, gfc_expr *mold, gfc_expr *size,
* If SIZE is present, the result is an array of rank one and size SIZE.
*/
if (result_elt_size == 0 && *source_size > 0 && !size
- && mold->expr_type == EXPR_ARRAY)
+ && (mold->expr_type == EXPR_ARRAY || mold->rank))
{
gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L is an "
"array and shall not have storage size 0 when %<SOURCE%> "
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index 279d9b3..ed82a94 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -312,7 +312,8 @@ gfc_copy_expr (gfc_expr *p)
break;
case BT_CHARACTER:
- if (p->representation.string)
+ if (p->representation.string
+ && p->ts.kind == gfc_default_character_kind)
q->value.character.string
= gfc_char_to_widechar (q->representation.string);
else
diff --git a/gcc/fortran/target-memory.cc b/gcc/fortran/target-memory.cc
index 361907b..7ce7d73 100644
--- a/gcc/fortran/target-memory.cc
+++ b/gcc/fortran/target-memory.cc
@@ -365,7 +365,8 @@ gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer,
static size_t
-interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
+interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result,
+ bool convert_widechar)
{
gfc_constructor_base base = NULL;
size_t array_size = 1;
@@ -390,7 +391,7 @@ interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
gfc_constructor_append_expr (&base, e, &result->where);
ptr += gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e,
- true);
+ convert_widechar);
}
result->value.constructor = base;
@@ -580,7 +581,7 @@ gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
gfc_expr *result, bool convert_widechar)
{
if (result->expr_type == EXPR_ARRAY)
- return interpret_array (buffer, buffer_size, result);
+ return interpret_array (buffer, buffer_size, result, convert_widechar);
switch (result->ts.type)
{
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2f0c8a4..cfb6eac 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9102,6 +9102,10 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
continue;
}
+ /* Do not broadcast a caf_token. These are local to the image. */
+ if (attr->caf_token)
+ continue;
+
add_when_allocated = NULL_TREE;
if (cmp_has_alloc_comps
&& !c->attr.pointer && !c->attr.proc_pointer)
@@ -9134,10 +9138,13 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
if (attr->dimension)
{
tmp = gfc_get_element_type (TREE_TYPE (comp));
- ubound = gfc_full_array_size (&tmpblock, comp,
- c->ts.type == BT_CLASS
- ? CLASS_DATA (c)->as->rank
- : c->as->rank);
+ if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
+ ubound = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (comp));
+ else
+ ubound = gfc_full_array_size (&tmpblock, comp,
+ c->ts.type == BT_CLASS
+ ? CLASS_DATA (c)->as->rank
+ : c->as->rank);
}
else
{
@@ -9145,26 +9152,39 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
ubound = build_int_cst (gfc_array_index_type, 1);
}
- cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
- &ubound, 1,
- GFC_ARRAY_ALLOCATABLE, false);
+ /* Treat strings like arrays. Or the other way around, do not
+ * generate an additional array layer for scalar components. */
+ if (attr->dimension || c->ts.type == BT_CHARACTER)
+ {
+ cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
+ &ubound, 1,
+ GFC_ARRAY_ALLOCATABLE, false);
- cdesc = gfc_create_var (cdesc, "cdesc");
- DECL_ARTIFICIAL (cdesc) = 1;
+ cdesc = gfc_create_var (cdesc, "cdesc");
+ DECL_ARTIFICIAL (cdesc) = 1;
- gfc_add_modify (&tmpblock, gfc_conv_descriptor_dtype (cdesc),
- gfc_get_dtype_rank_type (1, tmp));
- gfc_conv_descriptor_lbound_set (&tmpblock, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_stride_set (&tmpblock, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&tmpblock, cdesc,
- gfc_index_zero_node, ubound);
+ gfc_add_modify (&tmpblock, gfc_conv_descriptor_dtype (cdesc),
+ gfc_get_dtype_rank_type (1, tmp));
+ gfc_conv_descriptor_lbound_set (&tmpblock, cdesc,
+ gfc_index_zero_node,
+ gfc_index_one_node);
+ gfc_conv_descriptor_stride_set (&tmpblock, cdesc,
+ gfc_index_zero_node,
+ gfc_index_one_node);
+ gfc_conv_descriptor_ubound_set (&tmpblock, cdesc,
+ gfc_index_zero_node, ubound);
+ }
+ else
+ /* Prevent warning. */
+ cdesc = NULL_TREE;
if (attr->dimension)
- comp = gfc_conv_descriptor_data_get (comp);
+ {
+ if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
+ comp = gfc_conv_descriptor_data_get (comp);
+ else
+ comp = gfc_build_addr_expr (NULL_TREE, comp);
+ }
else
{
gfc_se se;
@@ -9172,14 +9192,18 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
gfc_init_se (&se, NULL);
comp = gfc_conv_scalar_to_descriptor (&se, comp,
- c->ts.type == BT_CLASS
- ? CLASS_DATA (c)->attr
- : c->attr);
- comp = gfc_build_addr_expr (NULL_TREE, comp);
+ c->ts.type == BT_CLASS
+ ? CLASS_DATA (c)->attr
+ : c->attr);
+ if (c->ts.type == BT_CHARACTER)
+ comp = gfc_build_addr_expr (NULL_TREE, comp);
gfc_add_block_to_block (&tmpblock, &se.pre);
}
- gfc_conv_descriptor_data_set (&tmpblock, cdesc, comp);
+ if (attr->dimension || c->ts.type == BT_CHARACTER)
+ gfc_conv_descriptor_data_set (&tmpblock, cdesc, comp);
+ else
+ cdesc = comp;
tree fndecl;
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index fccf0a9..e680de1 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -2620,7 +2620,7 @@ conv_intrinsic_image_status (gfc_se *se, gfc_expr *expr)
else
gcc_unreachable ();
- se->expr = tmp;
+ se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind), tmp);
}
static void
@@ -2662,7 +2662,7 @@ conv_intrinsic_team_number (gfc_se *se, gfc_expr *expr)
else
gcc_unreachable ();
- se->expr = tmp;
+ se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind), tmp);
}
@@ -7255,12 +7255,13 @@ gfc_conv_intrinsic_popcnt_poppar (gfc_se * se, gfc_expr *expr, int parity)
/* Combine the results. */
if (parity)
- se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, result_type,
- call1, call2);
+ se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR,
+ integer_type_node, call1, call2);
else
- se->expr = fold_build2_loc (input_location, PLUS_EXPR, result_type,
- call1, call2);
+ se->expr = fold_build2_loc (input_location, PLUS_EXPR,
+ integer_type_node, call1, call2);
+ se->expr = convert (result_type, se->expr);
return;
}
@@ -11211,24 +11212,31 @@ conv_co_collective (gfc_code *code)
return gfc_finish_block (&block);
}
+ gfc_symbol *derived = code->ext.actual->expr->ts.type == BT_DERIVED
+ ? code->ext.actual->expr->ts.u.derived : NULL;
+
/* Handle the array. */
gfc_init_se (&argse, NULL);
- if (code->ext.actual->expr->rank == 0)
- {
- symbol_attribute attr;
- gfc_clear_attr (&attr);
- gfc_init_se (&argse, NULL);
- gfc_conv_expr (&argse, code->ext.actual->expr);
- gfc_add_block_to_block (&block, &argse.pre);
- gfc_add_block_to_block (&post_block, &argse.post);
- array = gfc_conv_scalar_to_descriptor (&argse, argse.expr, attr);
- array = gfc_build_addr_expr (NULL_TREE, array);
- }
- else
+ if (!derived || !derived->attr.alloc_comp
+ || code->resolved_isym->id != GFC_ISYM_CO_BROADCAST)
{
- argse.want_pointer = 1;
- gfc_conv_expr_descriptor (&argse, code->ext.actual->expr);
- array = argse.expr;
+ if (code->ext.actual->expr->rank == 0)
+ {
+ symbol_attribute attr;
+ gfc_clear_attr (&attr);
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr (&argse, code->ext.actual->expr);
+ gfc_add_block_to_block (&block, &argse.pre);
+ gfc_add_block_to_block (&post_block, &argse.post);
+ array = gfc_conv_scalar_to_descriptor (&argse, argse.expr, attr);
+ array = gfc_build_addr_expr (NULL_TREE, array);
+ }
+ else
+ {
+ argse.want_pointer = 1;
+ gfc_conv_expr_descriptor (&argse, code->ext.actual->expr);
+ array = argse.expr;
+ }
}
gfc_add_block_to_block (&block, &argse.pre);
@@ -11289,9 +11297,6 @@ conv_co_collective (gfc_code *code)
gcc_unreachable ();
}
- gfc_symbol *derived = code->ext.actual->expr->ts.type == BT_DERIVED
- ? code->ext.actual->expr->ts.u.derived : NULL;
-
if (derived && derived->attr.alloc_comp
&& code->resolved_isym->id == GFC_ISYM_CO_BROADCAST)
/* The derived type has the attribute 'alloc_comp'. */
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 3639aa2..9e0c01d 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -8539,11 +8539,12 @@ arith_code_with_undefined_signed_overflow (tree_code code)
its operand, carrying out the operation in the corresponding unsigned
type and converting the result back to the original type.
- Returns a sequence of statements that replace STMT and also contain
- a modified form of STMT itself. */
+ If IN_PLACE is true, adjust the stmt in place and return NULL.
+ Otherwise returns a sequence of statements that replace STMT and also
+ contain a modified form of STMT itself. */
gimple_seq
-rewrite_to_defined_overflow (gimple *stmt)
+rewrite_to_defined_overflow (gimple *stmt, bool in_place /* = false */)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -8568,9 +8569,24 @@ rewrite_to_defined_overflow (gimple *stmt)
if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
gimple_set_modified (stmt, true);
- gimple_seq_add_stmt (&stmts, stmt);
+ if (in_place)
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ if (stmts)
+ gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
+ stmts = NULL;
+ }
+ else
+ gimple_seq_add_stmt (&stmts, stmt);
gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
- gimple_seq_add_stmt (&stmts, cvt);
+ if (in_place)
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ gsi_insert_after (&gsi, cvt, GSI_SAME_STMT);
+ update_stmt (stmt);
+ }
+ else
+ gimple_seq_add_stmt (&stmts, cvt);
return stmts;
}
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 11e5732..82631a4 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -62,7 +62,7 @@ extern tree gimple_fold_indirect_ref (tree);
extern bool gimple_fold_builtin_sprintf (gimple_stmt_iterator *);
extern bool gimple_fold_builtin_snprintf (gimple_stmt_iterator *);
extern bool arith_code_with_undefined_signed_overflow (tree_code);
-extern gimple_seq rewrite_to_defined_overflow (gimple *);
+extern gimple_seq rewrite_to_defined_overflow (gimple *, bool = false);
extern void replace_call_with_value (gimple_stmt_iterator *, tree);
extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree);
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 8bc33ee..3dcaf42 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -2053,7 +2053,7 @@ const pass_data pass_data_waccess = {
GIMPLE_PASS,
"waccess",
OPTGROUP_NONE,
- TV_NONE,
+ TV_WARN_ACCESS, /* timer variable */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
@@ -3880,9 +3880,17 @@ pass_waccess::warn_invalid_pointer (tree ref, gimple *use_stmt,
bool maybe, bool equality /* = false */)
{
/* Avoid printing the unhelpful "<unknown>" in the diagnostics. */
- if (ref && TREE_CODE (ref) == SSA_NAME
- && (!SSA_NAME_VAR (ref) || DECL_ARTIFICIAL (SSA_NAME_VAR (ref))))
- ref = NULL_TREE;
+ if (ref && TREE_CODE (ref) == SSA_NAME)
+ {
+ tree var = SSA_NAME_VAR (ref);
+ if (!var)
+ ref = NULL_TREE;
+ /* Don't warn for cases like when a cdtor returns 'this' on ARM. */
+ else if (warning_suppressed_p (var, OPT_Wuse_after_free))
+ return;
+ else if (DECL_ARTIFICIAL (var))
+ ref = NULL_TREE;
+ }
location_t use_loc = gimple_location (use_stmt);
if (use_loc == UNKNOWN_LOCATION)
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index bf2f60c..cd4b613 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9552,7 +9552,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
== REFERENCE_TYPE))
decl = TREE_OPERAND (decl, 0);
}
- if (decl != orig_decl && DECL_P (decl) && indir_p)
+ if (decl != orig_decl && DECL_P (decl) && indir_p
+ && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ || (decl_ref
+ && TREE_CODE (TREE_TYPE (decl_ref)) == POINTER_TYPE)))
{
gomp_map_kind k
= ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
diff --git a/gcc/graph.cc b/gcc/graph.cc
index 9990c8e..bc29862 100644
--- a/gcc/graph.cc
+++ b/gcc/graph.cc
@@ -169,14 +169,14 @@ draw_cfg_nodes_no_loops (pretty_printer *pp, struct function *fun)
int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
int i, n;
- auto_sbitmap visited (last_basic_block_for_fn (cfun));
+ auto_sbitmap visited (last_basic_block_for_fn (fun));
bitmap_clear (visited);
n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, true);
for (i = n_basic_blocks_for_fn (fun) - n;
i < n_basic_blocks_for_fn (fun); i++)
{
- basic_block bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
+ basic_block bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]);
draw_cfg_node (pp, fun->funcdef_no, bb);
bitmap_set_bit (visited, bb->index);
}
@@ -248,7 +248,8 @@ draw_cfg_nodes_for_loop (pretty_printer *pp, int funcdef_no,
static void
draw_cfg_nodes (pretty_printer *pp, struct function *fun)
{
- if (loops_for_fn (fun))
+ /* ??? The loop and dominance APIs are dependent on fun == cfun. */
+ if (fun == cfun && loops_for_fn (fun))
draw_cfg_nodes_for_loop (pp, fun->funcdef_no, get_loop (fun, 0));
else
draw_cfg_nodes_no_loops (pp, fun);
@@ -267,7 +268,7 @@ draw_cfg_edges (pretty_printer *pp, struct function *fun)
edge e;
edge_iterator ei;
unsigned int idx = 0;
- FOR_EACH_BB_FN (bb, cfun)
+ FOR_EACH_BB_FN (bb, fun)
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (e->flags & EDGE_DFS_BACK)
@@ -275,13 +276,13 @@ draw_cfg_edges (pretty_printer *pp, struct function *fun)
idx++;
}
- mark_dfs_back_edges ();
- FOR_ALL_BB_FN (bb, cfun)
+ mark_dfs_back_edges (fun);
+ FOR_ALL_BB_FN (bb, fun)
draw_cfg_node_succ_edges (pp, fun->funcdef_no, bb);
/* Restore EDGE_DFS_BACK flag from dfs_back. */
idx = 0;
- FOR_EACH_BB_FN (bb, cfun)
+ FOR_EACH_BB_FN (bb, fun)
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (bitmap_bit_p (dfs_back, idx))
diff --git a/gcc/ipa-modref-tree.cc b/gcc/ipa-modref-tree.cc
index 97e497a..828994f 100644
--- a/gcc/ipa-modref-tree.cc
+++ b/gcc/ipa-modref-tree.cc
@@ -130,8 +130,7 @@ modref_access_node::update (poly_int64 parm_offset1,
else
{
if (dump_file)
- fprintf (dump_file,
- "--param param=modref-max-adjustments limit reached:");
+ fprintf (dump_file, "--param modref-max-adjustments limit reached:");
if (!known_eq (parm_offset, parm_offset1))
{
if (dump_file)
@@ -594,11 +593,11 @@ modref_access_node::insert (vec <modref_access_node, va_gc> *&accesses,
return -1;
if (dump_file && best2 >= 0)
fprintf (dump_file,
- "--param param=modref-max-accesses limit reached;"
+ "--param modref-max-accesses limit reached;"
" merging %i and %i\n", best1, best2);
else if (dump_file)
fprintf (dump_file,
- "--param param=modref-max-accesses limit reached;"
+ "--param modref-max-accesses limit reached;"
" merging with %i\n", best1);
modref_access_node::try_merge_with (accesses, best1);
if (best2 >= 0)
@@ -825,8 +824,7 @@ modref_access_node::insert_kill (vec<modref_access_node> &kills,
if ((int)kills.length () >= param_modref_max_accesses)
{
if (dump_file)
- fprintf (dump_file,
- "--param param=modref-max-accesses limit reached:");
+ fprintf (dump_file, "--param modref-max-accesses limit reached:");
return false;
}
a.adjustments = 0;
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index edb3b49..fdaa961 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -197,8 +197,7 @@ struct GTY((user)) modref_ref_node
{
if (dump_file)
fprintf (dump_file,
- "--param param=modref-max-accesses limit reached;"
- " collapsing\n");
+ "--param modref-max-accesses limit reached; collapsing\n");
collapse ();
}
return ret != 0;
@@ -252,7 +251,7 @@ struct GTY((user)) modref_base_node
if (ref && refs && refs->length () >= max_refs)
{
if (dump_file)
- fprintf (dump_file, "--param param=modref-max-refs limit reached;"
+ fprintf (dump_file, "--param modref-max-refs limit reached;"
" using 0\n");
ref = 0;
ref_node = search (ref);
@@ -344,12 +343,12 @@ struct GTY((user)) modref_tree
if (base_node)
{
if (dump_file)
- fprintf (dump_file, "--param param=modref-max-bases"
+ fprintf (dump_file, "--param modref-max-bases"
" limit reached; using ref\n");
return base_node;
}
if (dump_file)
- fprintf (dump_file, "--param param=modref-max-bases"
+ fprintf (dump_file, "--param modref-max-bases"
" limit reached; using 0\n");
base = 0;
base_node = search (base);
diff --git a/gcc/optabs.def b/gcc/optabs.def
index bb46083..801310e 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -331,6 +331,10 @@ OPTAB_D (sinh_optab, "sinh$a2")
OPTAB_D (tan_optab, "tan$a2")
OPTAB_D (tanh_optab, "tanh$a2")
+OPTAB_D (fegetround_optab, "fegetround$a")
+OPTAB_D (feclearexcept_optab, "feclearexcept$a")
+OPTAB_D (feraiseexcept_optab, "feraiseexcept$a")
+
/* C99 implementations of fmax/fmin. */
OPTAB_D (fmax_optab, "fmax$a3")
OPTAB_D (fmin_optab, "fmin$a3")
diff --git a/gcc/opts.cc b/gcc/opts.cc
index f21c821..7d30deb 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -3158,6 +3158,10 @@ common_handle_option (struct gcc_options *opts,
dc->tabstop = value;
break;
+ case OPT_freport_bug:
+ dc->report_bug = value;
+ break;
+
default:
/* If the flag was handled in a standard way, assume the lack of
processing here is intentional. */
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index a61ac89..b092ef4 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -629,7 +629,7 @@ access_ref::phi () const
ARG refers to the null pointer. Return true on success and false
on failure. */
-bool
+void
access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
int ostype, bool skip_null,
ssa_name_limit_t &snlim, pointer_query &qry)
@@ -637,8 +637,16 @@ access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
access_ref aref;
if (!compute_objsize_r (arg, stmt, false, ostype, &aref, snlim, &qry)
|| aref.sizrng[0] < 0)
- /* This may be a PHI with all null pointer arguments. */
- return false;
+ {
+ /* This may be a PHI with all null pointer arguments. Handle it
+ conservatively by setting all properties to the most permissive
+ values. */
+ base0 = false;
+ offrng[0] = offrng[1] = 0;
+ add_max_offset ();
+ set_max_size_range ();
+ return;
+ }
if (all_refs)
{
@@ -675,13 +683,13 @@ access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
if (arg_known_size)
sizrng[0] = aref.sizrng[0];
- return true;
+ return;
}
/* Disregard null pointers in PHIs with two or more arguments.
TODO: Handle this better! */
if (nullp)
- return true;
+ return;
const bool known_size = (sizrng[0] != 0 || sizrng[1] != maxobjsize);
@@ -717,7 +725,7 @@ access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
sizrng[0] = minsize;
parmarray = merged_parmarray;
- return true;
+ return;
}
/* Determine and return the largest object to which *THIS refers. If
@@ -755,14 +763,12 @@ access_ref::get_ref (vec<access_ref> *all_refs,
access_ref aref;
tree arg1 = gimple_assign_rhs1 (def_stmt);
- if (!aref.merge_ref (all_refs, arg1, def_stmt, ostype, false,
- *psnlim, *qry))
- return NULL_TREE;
+ aref.merge_ref (all_refs, arg1, def_stmt, ostype, false,
+ *psnlim, *qry);
tree arg2 = gimple_assign_rhs2 (def_stmt);
- if (!aref.merge_ref (all_refs, arg2, def_stmt, ostype, false,
- *psnlim, *qry))
- return NULL_TREE;
+ aref.merge_ref (all_refs, arg2, def_stmt, ostype, false,
+ *psnlim, *qry);
if (pref && pref != this)
{
@@ -801,15 +807,23 @@ access_ref::get_ref (vec<access_ref> *all_refs,
phi_ref = *pref;
}
+ const offset_int maxobjsize = wi::to_offset (max_object_size ());
const unsigned nargs = gimple_phi_num_args (phi_stmt);
for (unsigned i = 0; i < nargs; ++i)
{
access_ref phi_arg_ref;
bool skip_null = i || i + 1 < nargs;
tree arg = gimple_phi_arg_def (phi_stmt, i);
- if (!phi_ref.merge_ref (all_refs, arg, phi_stmt, ostype, skip_null,
- *psnlim, *qry))
- return NULL_TREE;
+ phi_ref.merge_ref (all_refs, arg, phi_stmt, ostype, skip_null,
+ *psnlim, *qry);
+
+ if (!phi_ref.base0
+ && phi_ref.sizrng[0] == 0
+ && phi_ref.sizrng[1] >= maxobjsize)
+ /* When an argument results in the most permissive result,
+ the remaining arguments cannot constrain it. Short-circuit
+ the evaluation. */
+ break;
}
if (phi_ref.sizrng[0] < 0)
@@ -1627,36 +1641,6 @@ pointer_query::dump (FILE *dump_file, bool contents /* = false */)
}
fputc ('\n', dump_file);
-
- {
- fputs ("\npointer_query cache contents (again):\n", dump_file);
-
- tree var;
- unsigned i;
- FOR_EACH_SSA_NAME (i, var, cfun)
- {
- if (TREE_CODE (TREE_TYPE (var)) != POINTER_TYPE)
- continue;
-
- for (unsigned ost = 0; ost != 2; ++ost)
- {
- if (const access_ref *cache_ref = get_ref (var, ost))
- {
- unsigned ver = SSA_NAME_VERSION (var);
- fprintf (dump_file, " %u.%u: ", ver, ost);
- if (tree name = ssa_name (ver))
- {
- print_generic_expr (dump_file, name);
- fputs (" = ", dump_file);
- }
- else
- fprintf (dump_file, " _%u = ", ver);
-
- cache_ref->dump (dump_file);
- }
- }
- }
- }
}
/* A helper of compute_objsize_r() to determine the size from an assignment
diff --git a/gcc/pointer-query.h b/gcc/pointer-query.h
index 7dc965b..dbdcd59 100644
--- a/gcc/pointer-query.h
+++ b/gcc/pointer-query.h
@@ -67,7 +67,7 @@ struct access_ref
gphi *phi () const;
/* Merge the result for a pointer with *THIS. */
- bool merge_ref (vec<access_ref> *all_refs, tree, gimple *, int, bool,
+ void merge_ref (vec<access_ref> *all_refs, tree, gimple *, int, bool,
ssa_name_limit_t &, pointer_query &);
/* Return the object to which REF refers. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6d22984..012e2c3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,274 @@
+2022-01-27 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/analyzer/data-model-1.c: Add dg-message directives for
+ expected region creation events.
+ * gcc.dg/analyzer/malloc-1.c: Likewise.
+ * gcc.dg/analyzer/memset-CVE-2017-18549-1.c: Likewise.
+ * gcc.dg/analyzer/pr101547.c: Likewise.
+ * gcc.dg/analyzer/pr101875.c: Likewise.
+ * gcc.dg/analyzer/pr101962.c: Likewise.
+ * gcc.dg/analyzer/pr104224.c: Likewise.
+ * gcc.dg/analyzer/pr94047.c: Likewise.
+ * gcc.dg/analyzer/symbolic-1.c: Likewise.
+ * gcc.dg/analyzer/uninit-1.c: Likewise.
+ * gcc.dg/analyzer/uninit-4.c: Likewise.
+ * gcc.dg/analyzer/uninit-alloca.c: New test.
+ * gcc.dg/analyzer/uninit-pr94713.c: Add dg-message directive for
+ expected region creation event.
+ * gcc.dg/analyzer/uninit-pr94714.c: Likewise.
+ * gcc.dg/analyzer/zlib-3.c: Likewise.
+
+2022-01-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/104245
+ PR c++/51344
+ * g++.dg/lto/alignas1_0.C: New test.
+
+2022-01-27 Uroš Bizjak <ubizjak@gmail.com>
+
+ * gfortran.dg/ieee/signaling_1.f90 (dg-do):
+ Run only on non-ia32 targets.
+ * gfortran.dg/ieee/signaling_2.f90 (dg-do): Ditto.
+ * gfortran.dg/ieee/signaling_3.f90 (dg-do): Ditto.
+
+2022-01-27 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104128
+ * gfortran.dg/transfer_simplify_14.f90: New test.
+
+2022-01-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/82632
+ * g++.dg/cpp1z/class-deduction104.C: New test.
+ * g++.dg/cpp1z/class-deduction105.C: New test.
+
+2022-01-27 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/84784
+ * gfortran.dg/pr84784.f90: New test.
+
+2022-01-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/99895
+ * g++.dg/cpp2a/consteval-memfn1.C: New test.
+ * g++.dg/cpp2a/consteval-memfn2.C: New test.
+ * g++.dg/cpp2a/consteval28.C: New test.
+
+2022-01-27 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/92944
+ PR c++/103678
+ * g++.dg/cpp2a/concepts-partial-spec10.C: New test.
+ * g++.dg/cpp2a/concepts-partial-spec11.C: New test.
+
+2022-01-27 Marek Polacek <polacek@redhat.com>
+
+ PR c++/101988
+ * g++.dg/cpp1z/class-deduction-new1.C: New test.
+ * g++.dg/cpp23/auto-array2.C: New test.
+
+2022-01-27 Kewen Lin <linkw@linux.ibm.com>
+
+ PR target/103702
+ * gcc.target/powerpc/pr103702.c: New test.
+
+2022-01-27 Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR middle-end/103642
+ * c-c++-common/gomp/pr103642.c: New test.
+
+2022-01-27 Andrew Pinski <apinski@marvell.com>
+
+ PR target/104201
+ * gcc.target/aarch64/branch-protection-attr.c: Fix quoting for
+ the expected error message on line 5 of leaf.
+
+2022-01-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/104196
+ * gcc.c-torture/execute/pr104196.c: New test.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104239
+ * gcc.target/powerpc/pr104239-3.c: New test.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104239
+ * gcc.target/powerpc/pr104239-1.c: New test.
+ * gcc.target/powerpc/pr104239-2.c: New test.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/104226
+ * g++.dg/cpp0x/constexpr-104226.C: New test.
+
+2022-01-26 Marek Polacek <polacek@redhat.com>
+
+ PR target/104213
+ * g++.dg/warn/Wuse-after-free2.C: New test.
+ * g++.dg/warn/Wuse-after-free3.C: New test.
+
+2022-01-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/104235
+ * g++.dg/parse/template-keyword2.C: New test.
+
+2022-01-26 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/tree-ssa/modref-7.c: Update scanned patterns.
+ * gcc.dg/tree-ssa/modref-8.c: Likewise.
+
+2022-01-26 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/104224
+ * gcc.dg/analyzer/pr104224.c: New test.
+
+2022-01-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104188
+ * gcc.target/i386/pr104188.c: Add dg-require-effective-target
+ sse2_runtime. Add -msse2 to dg-options.
+
+2022-01-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/103057
+ * g++.dg/cpp0x/alias-decl-void1.C: New test.
+
+2022-01-25 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104227
+ * gfortran.dg/transfer_check_6.f90: New test.
+
+2022-01-25 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104212
+ * gfortran.dg/argument_checking_26.f90: New test.
+
+2022-01-25 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101532
+ PR c++/104225
+ * g++.dg/cpp0x/nsdmi-template21.C: New test.
+ * g++.dg/cpp0x/nsdmi-template21a.C: New test.
+
+2022-01-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/59950
+ * g++.dg/init/assign2.C: New test.
+
+2022-01-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104214
+ * gcc.dg/vect/pr81196-2.c: New variant testcase only
+ requiring vect_int.
+
+2022-01-25 Francois-Xavier Coudert <fxcoudert@gmail.com>
+
+ * gfortran.dg/ieee/signaling_3.f90: Skip test on 32-bit x86/x86_64.
+
+2022-01-25 Francois-Xavier Coudert <fxcoudert@gmail.com>
+
+ * gfortran.dg/ieee/signaling_1.f90: Fix test.
+
+2022-01-24 Marek Polacek <polacek@redhat.com>
+
+ PR preprocessor/104030
+ * c-c++-common/Wbidi-chars-10.c: Turn on UCN checking.
+ * c-c++-common/Wbidi-chars-11.c: Likewise.
+ * c-c++-common/Wbidi-chars-14.c: Likewise.
+ * c-c++-common/Wbidi-chars-16.c: Likewise.
+ * c-c++-common/Wbidi-chars-17.c: Likewise.
+ * c-c++-common/Wbidi-chars-4.c: Likewise.
+ * c-c++-common/Wbidi-chars-5.c: Likewise.
+ * c-c++-common/Wbidi-chars-6.c: Likewise.
+ * c-c++-common/Wbidi-chars-7.c: Likewise.
+ * c-c++-common/Wbidi-chars-8.c: Likewise.
+ * c-c++-common/Wbidi-chars-9.c: Likewise.
+ * c-c++-common/Wbidi-chars-ranges.c: Likewise.
+ * c-c++-common/Wbidi-chars-18.c: New test.
+ * c-c++-common/Wbidi-chars-19.c: New test.
+ * c-c++-common/Wbidi-chars-20.c: New test.
+ * c-c++-common/Wbidi-chars-21.c: New test.
+ * c-c++-common/Wbidi-chars-22.c: New test.
+ * c-c++-common/Wbidi-chars-23.c: New test.
+
+2022-01-24 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.dg/ieee/signaling_1.f90: Do not require issignaling.
+ * gfortran.dg/ieee/signaling_2.f90: Add comment.
+ * gfortran.dg/ieee/signaling_3.f90: New test.
+
+2022-01-24 Raoni Fassina Firmino <raoni@linux.ibm.com>
+
+ PR target/94193
+ * gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-1.c: New test.
+ * gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-2.c: New test.
+ * gcc.target/powerpc/builtin-fegetround.c: New test.
+
+2022-01-24 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/104173
+ * g++.dg/cpp0x/ref-qual21.C: New test.
+
+2022-01-24 Richard Biener <rguenther@suse.de>
+ Jiufu Guo <guojiufu@linux.ibm.com>
+
+ PR tree-optimization/100740
+ PR tree-optimization/101508
+ PR tree-optimization/101972
+ PR tree-optimization/102131
+ * gcc.dg/torture/pr100740.c: New testcase.
+ * gcc.dg/torture/pr101508.c: Likewise.
+ * gcc.dg/torture/pr101972.c: Likewise.
+ * gcc.dg/torture/pr102131-1.c: Likewise.
+ * gcc.dg/torture/pr102131-2.c: Likewise.
+ * gcc.dg/torture/pr102131-3.c: Likewise.
+ * gcc.dg/torture/pr102131-4.c: Likewise.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/104158
+ * gcc.dg/sancov/pr104158-7.c: Adjust for repeating of arguments
+ being allowed.
+
+2022-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/104158
+ * gcc.dg/spellcheck-options-24.c: New test.
+ * gcc.dg/sancov/pr104158-1.c: New test.
+ * gcc.dg/sancov/pr104158-2.c: New test.
+ * gcc.dg/sancov/pr104158-3.c: New test.
+ * gcc.dg/sancov/pr104158-4.c: New test.
+ * gcc.dg/sancov/pr104158-5.c: New test.
+ * gcc.dg/sancov/pr104158-6.c: New test.
+ * gcc.dg/sancov/pr104158-7.c: New test.
+
+2022-01-24 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/attribute-19.c: Add -misa-spec=2.2
+
+2022-01-24 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ PR tree-optimization/102087
+ * gcc.dg/pr102087_1.c: New test.
+
+2022-01-24 LiaoShihua <shihua@iscas.ac.cn>
+
+ * gcc.target/riscv/arch-9.c: Update the check info.
+ * gcc.target/riscv/arch-10.c: Ditto.
+ * gcc.target/riscv/arch-12.c: Ditto.
+
+2022-01-24 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/analyzer/torture/pr104159.c: Ignore psabi warning.
+
+2022-01-24 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/104188
+ * gcc.target/i386/pr104188.c: New test.
+
2022-01-23 Will Wray <wjwray@gmail.com>
PR c++/55227
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-10.c b/gcc/testsuite/c-c++-common/Wbidi-chars-10.c
index 3f851b6..cdcdce2 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-10.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-10.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn" } */
/* More nesting testing. */
/* RLE‫ LRI⁦ PDF‬ PDI⁩*/
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-11.c b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c
index 270ce23..ea83029 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-11.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn" } */
/* Test that we warn when mixing UCN and UTF-8. */
int LRE_‪_PDF_\u202c;
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-14.c b/gcc/testsuite/c-c++-common/Wbidi-chars-14.c
index ba5f75d..cb6b05e 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-14.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-14.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn" } */
/* Test PDI handling, which also pops any subsequent LREs, RLEs, LROs,
or RLOs. */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-16.c b/gcc/testsuite/c-c++-common/Wbidi-chars-16.c
index baa0159..eaf0ec9 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-16.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-16.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=any" } */
+/* { dg-options "-Wbidi-chars=any,ucn" } */
/* Test LTR/RTL chars. */
/* LTR<‎> */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-17.c b/gcc/testsuite/c-c++-common/Wbidi-chars-17.c
index 07cb432..3419221 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-17.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-17.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn" } */
/* Test LTR/RTL chars. */
/* LTR<‎> */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-18.c b/gcc/testsuite/c-c++-common/Wbidi-chars-18.c
new file mode 100644
index 0000000..ae586d5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-18.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/104030 */
+/* { dg-do compile } */
+/* By default, don't warn about UCNs. */
+
+const char *
+fn ()
+{
+ const char *aText = "\u202D" "abc";
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
+ return aText;
+}
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-19.c b/gcc/testsuite/c-c++-common/Wbidi-chars-19.c
new file mode 100644
index 0000000..9985c3b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-19.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/104030 */
+/* { dg-do compile } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn" } */
+
+const char *
+fn ()
+{
+ const char *aText = "\u202D" "abc";
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
+ return aText;
+}
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-20.c b/gcc/testsuite/c-c++-common/Wbidi-chars-20.c
new file mode 100644
index 0000000..859f3d5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-20.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/104030 */
+/* { dg-do compile } */
+/* { dg-options "-Wbidi-chars=any" } */
+
+const char *
+fn ()
+{
+ const char *aText = "\u202D" "abc";
+/* { dg-bogus "U\\+202D" "" { target *-*-* } .-1 } */
+ return aText;
+}
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-21.c b/gcc/testsuite/c-c++-common/Wbidi-chars-21.c
new file mode 100644
index 0000000..2720b8a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-21.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/104030 */
+/* { dg-do compile } */
+/* { dg-options "-Wbidi-chars=ucn,any" } */
+
+const char *
+fn ()
+{
+ const char *aText = "\u202D" "abc";
+/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */
+ return aText;
+}
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-22.c b/gcc/testsuite/c-c++-common/Wbidi-chars-22.c
new file mode 100644
index 0000000..f960e59
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-22.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/104030 */
+/* { dg-do compile } */
+/* { dg-options "-Wbidi-chars=none,ucn" } */
+
+const char *
+fn ()
+{
+ const char *aText = "\u202D" "abc";
+/* { dg-bogus "" "" { target *-*-* } .-1 } */
+ return aText;
+}
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-23.c b/gcc/testsuite/c-c++-common/Wbidi-chars-23.c
new file mode 100644
index 0000000..7de0a11
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-23.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/104030 */
+/* { dg-do compile } */
+/* { dg-options "-Wbidi-chars=ucn" } */
+
+const char *
+fn ()
+{
+ const char *aText = "\u202D" "abc";
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
+ return aText;
+}
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-4.c b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c
index 639e5c6..d2f0739 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-4.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=any -Wno-multichar -Wno-overflow" } */
+/* { dg-options "-Wbidi-chars=any,ucn -Wno-multichar -Wno-overflow" } */
/* Test all bidi chars in various contexts (identifiers, comments,
string literals, character constants), both UCN and UTF-8. The bidi
chars here are properly terminated, except for the character constants. */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-5.c b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c
index 68cb053..ad49498 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-5.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired -Wno-multichar -Wno-overflow" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn -Wno-multichar -Wno-overflow" } */
/* Test all bidi chars in various contexts (identifiers, comments,
string literals, character constants), both UCN and UTF-8. The bidi
chars here are properly terminated, except for the character constants. */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-6.c b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c
index 0ce6fff..8c1c1b2 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-6.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired" } */
+/* { dg-options "-Wbidi-chars=ucn,unpaired" } */
/* Test nesting of bidi chars in various contexts. */
/* Terminated by the wrong char: */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-7.c b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c
index d012d42..3270952 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-7.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=any" } */
+/* { dg-options "-Wbidi-chars=any,ucn" } */
/* Test we ignore UCNs in comments. */
// a b c \u202a 1 2 3
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-8.c b/gcc/testsuite/c-c++-common/Wbidi-chars-8.c
index 4f54c50..3983168 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-8.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-8.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=any" } */
+/* { dg-options "-Wbidi-chars=any,ucn" } */
/* Test \u vs \U. */
int a_\u202A;
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-9.c b/gcc/testsuite/c-c++-common/Wbidi-chars-9.c
index e2af1b1..0ddb0d9 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-9.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-9.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn" } */
/* Test that we properly separate bidi contexts (comment/identifier/character
constant/string literal). */
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c b/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c
index 298750a..0c71f30 100644
--- a/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-ranges.c
@@ -1,6 +1,6 @@
/* PR preprocessor/103026 */
/* { dg-do compile } */
-/* { dg-options "-Wbidi-chars=unpaired -fdiagnostics-show-caret" } */
+/* { dg-options "-Wbidi-chars=unpaired,ucn -fdiagnostics-show-caret" } */
/* Verify that we escape and underline pertinent bidirectional
control characters when quoting the source. */
diff --git a/gcc/testsuite/c-c++-common/gomp/pr103642.c b/gcc/testsuite/c-c++-common/gomp/pr103642.c
new file mode 100644
index 0000000..bbd0896
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr103642.c
@@ -0,0 +1,34 @@
+/* PR middle-end/103642 */
+/* { dg-do compile } */
+
+#include <stdlib.h>
+
+typedef struct
+{
+ int *a;
+} S;
+
+typedef struct
+{
+ S *s;
+ int *ptr;
+} T;
+
+#define N 10
+
+int main (void)
+{
+ T t;
+ t.s = (S *) malloc (sizeof (S));
+ t.s->a = (int *) malloc (sizeof(int) * N);
+
+ #pragma omp target map(from: t.s->a[:N])
+ {
+ t.s->a[0] = 1;
+ }
+
+ free (t.s->a);
+ free (t.s);
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-void1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-void1.C
new file mode 100644
index 0000000..accc1a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-void1.C
@@ -0,0 +1,18 @@
+// PR c++/103057
+// { dg-do compile { target c++11 } }
+
+template <class T> struct A { };
+template <class T> struct B { using type = A<T>; };
+template <class T> struct C {
+ using type = typename T::foo; // { dg-error "int" }
+};
+template <class T> using L = B<void>;
+
+template <class T>
+typename L<typename C<T>::type>::type
+f(T) { };
+
+int main()
+{
+ f(42); // { dg-error "no match" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-104226.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-104226.C
new file mode 100644
index 0000000..a44f417
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-104226.C
@@ -0,0 +1,15 @@
+// PR c++/104226
+// { dg-do compile }
+// { dg-options "-Wno-psabi" }
+
+typedef unsigned short __attribute__((__vector_size__(16))) U;
+typedef unsigned int __attribute__((__vector_size__(16))) V;
+typedef unsigned int __attribute__((__vector_size__(32))) W;
+
+U
+foo (void)
+{
+ return __builtin_convertvector (__builtin_shufflevector ((V){}, (W){},
+ 0, 0, 1, 0,
+ 5, 5, 0, 2), U);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C
index ac4e631..3df8829 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C
@@ -3,7 +3,7 @@
template <class... Ts>
void f() {
- [] { struct S : Ts { }; }; // { dg-error "not expanded" }
+ [] { struct S : Ts { }; }; // { dg-message "" }
}
int main() {
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C
index 185aa03..4634f16 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C
@@ -3,6 +3,6 @@
template <int... E>
void f() {
- [] { enum e { e = E }; }; // { dg-error "not expanded" }
+ [] { enum e { e = E }; }; // { dg-message "" }
}
template void f<>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C
new file mode 100644
index 0000000..810b4a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C
@@ -0,0 +1,9 @@
+// PR c++/100198
+// { dg-do compile { target c++11 } }
+
+template <int... E>
+void f() {
+ ([] { enum e { e = E }; }(), ...); // { dg-bogus "" "" { xfail *-*-* } }
+}
+
+template void f<0>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C
new file mode 100644
index 0000000..730215a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C
@@ -0,0 +1,14 @@
+// PR c++/100030
+// { dg-do compile { target c++11 } }
+
+template <class... Ts>
+void sink(Ts...);
+
+template <class... Ts>
+void f(Ts...) {
+ sink([] { struct alignas(Ts) S {}; }...); // { dg-bogus "" "" { xfail *-*-* } }
+}
+
+int main() {
+ f(0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C
new file mode 100644
index 0000000..8e48e38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C
@@ -0,0 +1,13 @@
+// PR c++/100282
+// { dg-do compile { target c++11 } }
+
+template <typename... Ts>
+void
+local_class ()
+{
+ int { []{ struct ZZ : Ts {}; }... }; // { dg-bogus "" "" { xfail *-*-* } }
+}
+
+template // <>
+void
+local_class<int> ();
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template21.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template21.C
new file mode 100644
index 0000000..79d43a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template21.C
@@ -0,0 +1,8 @@
+// PR c++/101532
+// { dg-do compile { target c++11 } }
+
+struct A { private: ~A(); };
+
+template<class> struct B { A a = A(); }; // { dg-error "private" }
+
+B<int> b; // { dg-error "deleted" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template21a.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template21a.C
new file mode 100644
index 0000000..08fd37b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template21a.C
@@ -0,0 +1,10 @@
+// PR c++/104225
+// { dg-do compile { target c++11 } }
+
+struct A { private: ~A(); };
+
+template<class> struct B { A a = A(); }; // { dg-error "private" }
+
+int main() {
+ new B<int>; // { dg-error "deleted" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual21.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual21.C
new file mode 100644
index 0000000..7f867c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual21.C
@@ -0,0 +1,23 @@
+// PR c++/104173
+// { dg-do compile { target c++11 } }
+
+struct QString {
+ QString toLower() &&;
+};
+
+struct QCoreApplication {
+ static QString applicationName();
+};
+
+QCoreApplication* instance();
+
+void f() {
+ instance()->applicationName().toLower();
+}
+
+template<class...>
+void g() {
+ instance()->applicationName().toLower();
+}
+
+template void g<>();
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction-new1.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction-new1.C
new file mode 100644
index 0000000..7028335
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction-new1.C
@@ -0,0 +1,16 @@
+// PR c++/101988
+// { dg-do compile { target c++17 } }
+
+template<typename T>
+struct A {
+ A(T);
+ A();
+};
+auto p1 = new A[]{1}; // { dg-error "creating array of template placeholder type" }
+auto p2 = new A[1]{1}; // { dg-error "invalid use of placeholder" }
+auto p3 = new A<int>[]{1};
+auto p4 = new A<int>[1]{1};
+auto p5 = new A[]{1, 2}; // { dg-error "creating array of template placeholder type" }
+auto p6 = new A<int>[]{1, 2};
+auto p7 = new A<int>[]{A(1), A(1)};
+auto p8 = new A<int>[2]{A(1), A(1)};
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction104.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction104.C
new file mode 100644
index 0000000..a34dea0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction104.C
@@ -0,0 +1,17 @@
+// PR c++/82632
+// { dg-do compile { target c++17 } }
+
+template<class T> struct Optional {
+ template<class U> Optional(U&&);
+};
+
+template<class A> Optional(A) -> Optional<A>;
+
+Optional opt(1729);
+Optional dupe(opt);
+
+using ty1 = decltype(opt);
+using ty1 = Optional<int>;
+
+using ty2 = decltype(dupe);
+using ty2 = Optional<int>;
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction105.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction105.C
new file mode 100644
index 0000000..73a9c6b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction105.C
@@ -0,0 +1,17 @@
+// PR c++/82632
+// { dg-do compile { target c++17 } }
+
+template<class T, int = 1>
+struct Foo {
+ Foo() = default;
+ Foo(const Foo&) = delete;
+
+ template<int I>
+ Foo(const Foo<T, I>&);
+};
+
+template<class T, int I>
+Foo(Foo<T,I>) -> Foo<T,I+1>;
+
+Foo<int> a;
+Foo b = a;
diff --git a/gcc/testsuite/g++.dg/cpp23/auto-array2.C b/gcc/testsuite/g++.dg/cpp23/auto-array2.C
new file mode 100644
index 0000000..0643168
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/auto-array2.C
@@ -0,0 +1,11 @@
+// PR c++/101988
+// { dg-do compile { target c++17 } }
+
+template<class T> struct A { A(); };
+A<int> a[3];
+auto (*p)[3] = &a;
+A<int> (*p2)[3] = &a;
+A (*p3)[3] = &a; // { dg-error "template placeholder type" }
+auto (&r)[3] = a;
+A<int> (&r2)[3] = a;
+A (&r3)[3] = a; // { dg-error "template placeholder type" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C
new file mode 100644
index 0000000..d45a1b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec10.C
@@ -0,0 +1,17 @@
+// PR c++/92944
+// { dg-do compile { target c++20 } }
+
+namespace ns { template<class T> struct A { }; }
+
+template<class T> requires true struct ns::A<T> { using type = T; };
+template<class T> requires false struct ns::A<T> { };
+
+template<class T> struct ns::A<T*> { };
+template<class T> requires true struct ns::A<T*> { using type = T; };
+template<class T> requires false struct ns::A<T*> { };
+
+using ty1 = ns::A<int>::type;
+using ty1 = int;
+
+using ty2 = ns::A<int*>::type;
+using ty2 = int;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec11.C b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec11.C
new file mode 100644
index 0000000..0333450
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-partial-spec11.C
@@ -0,0 +1,19 @@
+// PR c++/103678
+// { dg-do compile { target c++20 } }
+
+template<class>
+struct A {
+ template<class...>
+ struct B;
+};
+
+template<class A_t>
+template<class B_t>
+struct A<A_t>::B<B_t> {};
+
+template<class A_t>
+template<class B_t>
+requires requires {
+ typename B_t;
+}
+struct A<A_t>::B<B_t> {};
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C b/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C
new file mode 100644
index 0000000..910e7a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval-memfn1.C
@@ -0,0 +1,27 @@
+// PR c++/99895
+// { dg-do compile { target c++20 } }
+
+struct fixed_string {
+ consteval int size(int n) const {
+ if (n < 0) throw; // { dg-error "not a constant" }
+ return n;
+ }
+
+ static consteval int size_static(int n) {
+ if (n < 0) throw; // { dg-error "not a constant" }
+ return n;
+ }
+
+ consteval void operator()() const { }
+};
+
+template<class>
+void VerifyHash(fixed_string s) {
+ s.size(0); // { dg-bogus "" }
+ s.size(-1); // { dg-message "expansion of" }
+ s.size_static(0); // { dg-bogus "" }
+ s.size_static(-1); // { dg-message "expansion of" }
+ fixed_string::size_static(0); // { dg-bogus "" }
+ fixed_string::size_static(-1); // { dg-message "expansion of" }
+ s(); // { dg-bogus "" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval-memfn2.C b/gcc/testsuite/g++.dg/cpp2a/consteval-memfn2.C
new file mode 100644
index 0000000..71748f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval-memfn2.C
@@ -0,0 +1,34 @@
+// PR c++/99895
+// { dg-do compile { target c++20 } }
+
+static constexpr unsigned hash(const char* s, unsigned length)
+{
+ s=s;
+ return length;
+}
+template<unsigned N>
+struct fixed_string
+{
+ constexpr fixed_string(const char (&s)[N])
+ {
+ for (int i = 0; i < N; i++)
+ str[i] = s[i];
+ }
+ consteval const char* data() const { return str; }
+ consteval unsigned size() const { return N-1; }
+ char str[N];
+};
+template<unsigned expected_hash, fixed_string... s>
+static consteval void VerifyHash()
+{
+ (
+ [](auto){static_assert(hash(s.data(), s.size()) == expected_hash);}(s)
+ ,...);
+ // The compiler mistakenly translates s.data() into s.data(&s)
+ // and then complains that the call is not valid, because
+ // the function expects 0 parameters and 1 "was provided".
+}
+void foo()
+{
+ VerifyHash<5, "khaki", "plums">();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval28.C b/gcc/testsuite/g++.dg/cpp2a/consteval28.C
new file mode 100644
index 0000000..293a6be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval28.C
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++20 } }
+
+struct empty { };
+
+consteval void f(empty) { }
+
+template<class>
+void g(empty e) {
+ f(e);
+}
diff --git a/gcc/testsuite/g++.dg/init/assign2.C b/gcc/testsuite/g++.dg/init/assign2.C
new file mode 100644
index 0000000..72d1264
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/assign2.C
@@ -0,0 +1,6 @@
+// PR c++/59950
+
+ struct Foo {};
+
+ int f(Foo *p);
+ int n = f(&(Foo() = Foo()));
diff --git a/gcc/testsuite/g++.dg/lto/alignas1_0.C b/gcc/testsuite/g++.dg/lto/alignas1_0.C
new file mode 100644
index 0000000..a2fc72a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alignas1_0.C
@@ -0,0 +1,7 @@
+// PR c++/104245
+// { dg-lto-do assemble }
+// { dg-require-effective-target c++11 }
+
+template <typename T> struct A { alignas(T) alignas(int) int a; };
+struct B { B(const char *, const char *, int, int); A<int> b; };
+B c {"", "", 0, 0};
diff --git a/gcc/testsuite/g++.dg/parse/template-keyword2.C b/gcc/testsuite/g++.dg/parse/template-keyword2.C
new file mode 100644
index 0000000..ecd0667
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/template-keyword2.C
@@ -0,0 +1,8 @@
+// PR c++/104235
+
+template <class M>
+struct L: M {
+ using M::a;
+ void a();
+ void p() { this->template a<>(); }
+};
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free2.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free2.C
new file mode 100644
index 0000000..6d5f2bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuse-after-free2.C
@@ -0,0 +1,10 @@
+// PR target/104213
+// { dg-do compile }
+// { dg-options "-Wuse-after-free" }
+
+class C
+{
+ virtual ~C();
+};
+
+C::~C() {} // { dg-bogus "used after" }
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
new file mode 100644
index 0000000..1862ac8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
@@ -0,0 +1,16 @@
+// PR target/104213
+// { dg-do compile }
+// { dg-options "-Wuse-after-free" }
+// FIXME: We should not output the warning twice.
+
+struct A
+{
+ virtual ~A ();
+ void f ();
+};
+
+A::~A ()
+{
+ operator delete (this);
+ f (); // { dg-warning "used after" }
+} // { dg-warning "used after" }
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr104196.c b/gcc/testsuite/gcc.c-torture/execute/pr104196.c
new file mode 100644
index 0000000..80f267a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr104196.c
@@ -0,0 +1,19 @@
+/* PR tree-optimization/104196 */
+
+int a = 6;
+
+int
+main ()
+{
+ while (1)
+ {
+ int b = a < 0 && 0 < -__INT_MAX__ - a ? 0 : a;
+ if (b != 4096 - __INT_MAX__)
+ {
+ if (a < 6)
+ __builtin_abort ();
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
index 511ed4b..4318191 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
@@ -152,7 +152,7 @@ int test_12 (void)
/* Use of uninit value. */
int test_12a (void)
{
- int i;
+ int i; /* { dg-message "region created on stack here" } */
return i; /* { dg-warning "use of uninitialized value 'i'" } */
}
@@ -163,7 +163,7 @@ void test_12b (void *p, void *q)
int test_12c (void)
{
- int i;
+ int i; /* { dg-message "region created on stack here" } */
int j;
j = i; /* { dg-warning "use of uninitialized value 'i'" } */
@@ -349,7 +349,7 @@ void test_18 (int i)
void test_19 (void)
{
- int i, j;
+ int i, j; /* { dg-message "region created on stack here" } */
/* Compare two uninitialized locals. */
__analyzer_eval (i == j); /* { dg-warning "UNKNOWN" "unknown " } */
/* { dg-warning "use of uninitialized value 'i'" "uninit i" { target *-*-* } .-1 } */
@@ -633,7 +633,7 @@ void test_29a (struct coord p[])
void test_29b (void)
{
- struct coord p[11];
+ struct coord p[11]; /* { dg-message "region created on stack here" } */
struct coord *q;
p[0].x = 100024;
@@ -819,7 +819,7 @@ void test_36 (int i)
int test_37 (void)
{
- int *ptr;
+ int *ptr; /* { dg-message "region created on stack here" } */
return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */
}
@@ -827,7 +827,7 @@ int test_37 (void)
void test_37a (int i)
{
- int *ptr;
+ int *ptr; /* { dg-message "region created on stack here" } */
*ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index df2fc9c..3219f85 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -189,7 +189,7 @@ void test_15 (void)
void test_16 (void)
{
- void *p, *q;
+ void *p, *q; /* { dg-message "region created on stack here" } */
p = malloc (1024);
if (!p)
@@ -457,7 +457,7 @@ test_39 (int i)
int *
test_40 (int i)
{
- int *p = (int*)malloc(sizeof(int*));
+ int *p = (int*)malloc(sizeof(int*)); /* { dg-message "region created on heap here" } */
i = *p; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" "possibly-null" } */
/* { dg-warning "use of uninitialized value '\\*p'" "uninit" { target *-*-*} .-1 } */
return p;
diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c
index de9b5e3..b12408a 100644
--- a/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/memset-CVE-2017-18549-1.c
@@ -47,7 +47,7 @@ static int aac_send_raw_srb(/* [...snip...] */)
/* [...snip...] */
- struct aac_srb_reply reply;
+ struct aac_srb_reply reply; /* { dg-message "region created on stack here" } */
reply.status = ST_OK;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101547.c b/gcc/testsuite/gcc.dg/analyzer/pr101547.c
index 8791cff..b42e64c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr101547.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr101547.c
@@ -5,7 +5,7 @@ void
k2 (void)
{
char *setfiles[1];
- int i;
+ int i; /* { dg-message "region created on stack here" } */
setfiles[i] = fopen ("", ""); /* { dg-warning "use of uninitialized value 'i'" } */
} /* { dg-warning "leak of FILE" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101875.c b/gcc/testsuite/gcc.dg/analyzer/pr101875.c
index 5988b8e..7700c7d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr101875.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr101875.c
@@ -8,7 +8,7 @@ void
k2 (void)
{
char *setfiles[1];
- int i;
+ int i; /* { dg-message "region created on stack here" } */
setfiles[i] = fopen("", ""); /* { dg-warning "use of uninitialized value 'i'" } */
if (!setfiles[i]) /* { dg-warning "use of uninitialized value 'i'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/gcc.dg/analyzer/pr101962.c
index 7b83d03..d15820a 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr101962.c
@@ -16,7 +16,7 @@ maybe_inc_int_ptr (int *ptr)
int
test_1 (void)
{
- int stack;
+ int stack; /* { dg-message "region created on stack here" } */
int *a = &stack;
a = maybe_inc_int_ptr (a);
a = maybe_inc_int_ptr (a);
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104224.c b/gcc/testsuite/gcc.dg/analyzer/pr104224.c
new file mode 100644
index 0000000..b047c4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104224.c
@@ -0,0 +1,106 @@
+#include <stdio.h>
+
+struct test {
+ int one;
+ int two;
+};
+
+void func2(const struct test *t)
+{
+ if (t->one == 0)
+ printf("init func2\n");
+
+ if (t->two == 0) /* { dg-warning "uninitialized" } */
+ printf("uninit func2\n");
+}
+
+void func1(struct test *t)
+{
+ t->one = 1;
+ func2(t);
+}
+
+int func3(int num)
+{
+ if (num)
+ return num;
+ else
+ return 0;
+}
+
+void func4(int *a, int max)
+{
+ int i;
+ // skip the first
+ for (i=1; i<max; i++)
+ a[i] = 0;
+}
+
+void func5(const int *a, int max)
+{
+ /* a[0] is uninitialized, but the rest of the array is initialized. */
+ int i;
+ for (i=0; i<max; i++) {
+ if (a[i]) /* { dg-warning "uninitialized" "" { xfail *-*-* } } */
+ printf("func5: %d\n", i);
+ }
+}
+
+int func6(const int *num)
+{
+ if (*num) /* { dg-warning "uninitialized" } */
+ return *num; /* { dg-warning "uninitialized" } */
+ else
+ return 0;
+}
+
+int j;
+int func7(void)
+{
+ return j; /* { dg-bogus "uninitialized" } */
+}
+
+void func8(const int *a, int max)
+{
+ int i;
+ for (i=0; i<max; i++) {
+ if (a[i]) /* { dg-warning "uninitialized" } */
+ printf("func8: %d\n", i);
+ }
+}
+
+enum {RED, AMBER, GREEN, BLACK};
+
+int main(void)
+{
+ struct test t; /* { dg-message "region created on stack here" } */
+ int num; /* { dg-message "region created on stack here" } */
+ int arry[10];
+ int arry_2[10]; /* { dg-message "region created on stack here" } */
+ int go; /* { dg-message "region created on stack here" } */
+ int color = BLACK;
+
+ func1(&t);
+ func3(num); /* { dg-warning "use of uninitialized value 'num'" } */
+ func4(arry, 10);
+ func5(arry, 10);
+ func6(&num);
+
+ printf("num: %d\n", num); /* { dg-warning "use of uninitialized value 'num'" } */
+ printf("func7: %d\n", func7());
+ func8(arry_2, 10);
+
+ switch (color) {
+ case RED:
+ case AMBER:
+ go = 0;
+ break;
+ case GREEN:
+ go = 1;
+ break;
+ }
+
+ printf("go :%d\n", go); /* { dg-warning "use of uninitialized value 'go'" } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94047.c b/gcc/testsuite/gcc.dg/analyzer/pr94047.c
index d13da3e..a579673 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr94047.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94047.c
@@ -12,7 +12,7 @@ bar (struct list *l)
void
foo (void)
{
- struct list l;
+ struct list l; /* { dg-message "region created on stack here" } */
tlist t = l; /* { dg-warning "use of uninitialized value 'l'" } */
for (;;)
bar (&t);
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c
index 0eba646..2f4e00b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c
@@ -5,7 +5,7 @@
void test_1 (char a, char b, char c, char d, char e, char f,
int i, int j)
{
- char arr[1024];
+ char arr[1024]; /* { dg-message "region created on stack here" } */
arr[2] = a; /* (1) */
arr[3] = b; /* (2) */
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c
index 8fcdcd6..cb7b252 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c
@@ -2,13 +2,13 @@
int test_1 (void)
{
- int i;
+ int i; /* { dg-message "region created on stack here" } */
return i; /* { dg-warning "use of uninitialized value 'i'" } */
}
int test_2 (void)
{
- int i;
+ int i; /* { dg-message "region created on stack here" } */
return i * 2; /* { dg-warning "use of uninitialized value 'i'" } */
}
@@ -20,13 +20,13 @@ int test_3 (void)
int test_4 (void)
{
- int *p;
+ int *p; /* { dg-message "region created on stack here" } */
return *p; /* { dg-warning "use of uninitialized value 'p'" } */
}
int test_5 (int flag, int *q)
{
- int *p;
+ int *p; /* { dg-message "region created on stack here" } */
if (flag) /* { dg-message "following 'false' branch" } */
p = q;
@@ -39,6 +39,6 @@ int test_5 (int flag, int *q)
int test_6 (int i)
{
- int arr[10];
+ int arr[10]; /* { dg-message "region created on stack here" } */
return arr[i]; /* { dg-warning "use of uninitialized value 'arr\\\[i\\\]'" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-4.c b/gcc/testsuite/gcc.dg/analyzer/uninit-4.c
index 791b111..616cb34 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-4.c
@@ -14,7 +14,7 @@ struct foo
struct foo *__attribute__((noinline))
alloc_foo (int a, int b)
{
- struct foo *p = malloc (sizeof (struct foo));
+ struct foo *p = malloc (sizeof (struct foo)); /* { dg-message "region created on heap here" } */
if (!p)
return NULL;
p->i = a;
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c b/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c
new file mode 100644
index 0000000..5dd3f85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c
@@ -0,0 +1,7 @@
+/* { dg-require-effective-target alloca } */
+
+int test_1 (void)
+{
+ int *p = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */
+ return *p; /* { dg-warning "use of uninitialized value '\\*p'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c
index cc337dc..e3bb8ce 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94713.c
@@ -3,7 +3,7 @@ void f2 (int);
int foo (void)
{
- int *p;
+ int *p; /* { dg-message "region created on stack here" } */
f1 (p); /* { dg-warning "use of uninitialized value 'p'" } */
f2 (p[0]); /* { dg-warning "use of uninitialized value 'p'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c
index df07f98..f120901 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr94714.c
@@ -3,7 +3,7 @@
int main (void)
{
int *p;
- int i;
+ int i; /* { dg-message "region created on stack here" } */
p = &i; /* { dg-bogus "uninitialized" } */
printf ("%d\n", p[0]); /* { dg-warning "use of uninitialized value '\\*p'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
index 57f5dcd..5098b4f 100644
--- a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c
@@ -46,7 +46,7 @@ static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e,
uInt mask;
register uInt *p;
inflate_huft *q;
- struct inflate_huft_s r;
+ struct inflate_huft_s r; /* { dg-message "region created on stack here" } */
inflate_huft *u[15];
register int w;
uInt x[15 + 1];
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/inline-13.c b/gcc/testsuite/gcc.dg/tree-ssa/inline-13.c
new file mode 100644
index 0000000..94d8a9c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/inline-13.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-early-inlining -fdump-tree-fixup_cfg3" } */
+
+int n;
+
+static int
+bar (void)
+{
+ int a;
+
+ n = 0;
+ a = 0;
+
+ return n;
+}
+
+__attribute__ ((pure, returns_twice)) int
+foo (void)
+{
+ n = bar () + 1;
+ foo ();
+
+ return 0;
+}
+
+/* Abnormal edges should be properly elided after IPA inlining of bar. */
+/* { dg-final { scan-tree-dump-times "bb" 1 "fixup_cfg3" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c
index 53ffa1c..b55d706 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c
@@ -10,4 +10,4 @@ int test(struct a *a, int p)
a->array[0] = 1;
}
/* All three accesses combine to one bigger access. */
-/* { dg-final { scan-tree-dump-not "param=modref-max-accesses" "modref1" } } */
+/* { dg-final { scan-tree-dump-not "--param modref-max-accesses" "modref1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
index 4a18e34..c51590f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
@@ -17,8 +17,8 @@ recurse (char *p, int n)
if (n)
recurse (p+1,n-1);
}
-/* { dg-final { scan-tree-dump-not "param=modref-max-accesses" "modref1" } } */
-/* { dg-final { scan-tree-dump "param=modref-max-adjustments" "modref1" } } */
+/* { dg-final { scan-tree-dump-not "--param modref-max-accesses" "modref1" } } */
+/* { dg-final { scan-tree-dump "--param modref-max-adjustments" "modref1" } } */
/* In set all accesses should merge together. */
/* { dg-final { scan-tree-dump "access: Parm 0 param offset:0 offset:0 size:8 max_size:40" "modref1" } } */
/* In recurse we should cap the recrusion after 8 attempts and set max_size to -1. */
diff --git a/gcc/testsuite/gcc.dg/vect/pr81196-2.c b/gcc/testsuite/gcc.dg/vect/pr81196-2.c
new file mode 100644
index 0000000..8d5ce6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr81196-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+void b (int *p)
+{
+ p = (int *)__builtin_assume_aligned(p, __BIGGEST_ALIGNMENT__);
+ int *q = p + 255;
+ for(; p < q; ++p, --q)
+ {
+ int t = *p;
+ *p = *q;
+ *q = t;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
index 229ce1c..1d6e55f 100644
--- a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
@@ -4,7 +4,7 @@ void __attribute__ ((target("branch-protection=leaf")))
foo1 ()
{
}
-/* { dg-error {invalid protection type \("leaf"\) in 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 5 } */
+/* { dg-error {invalid protection type \('leaf'\) in 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 5 } */
/* { dg-error {pragma or attribute 'target\("branch-protection=leaf"\)' is not valid} "" { target *-*-* } 5 } */
void __attribute__ ((target("branch-protection=none+pac-ret")))
diff --git a/gcc/testsuite/gcc.target/i386/pr104188.c b/gcc/testsuite/gcc.target/i386/pr104188.c
index c6f615b..3ddd3bc 100644
--- a/gcc/testsuite/gcc.target/i386/pr104188.c
+++ b/gcc/testsuite/gcc.target/i386/pr104188.c
@@ -1,5 +1,6 @@
/* { dg-do run { target avx512f } } */
-/* { dg-options "-O2 -mfpmath=sse" } */
+/* { dg-require-effective-target sse2_runtime } */
+/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
#include <x86intrin.h>
diff --git a/gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-1.c b/gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-1.c
new file mode 100644
index 0000000..4482e89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-1.c
@@ -0,0 +1,76 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-lm -fno-builtin" } */
+
+/* This testcase ensures that the builtins expand with the matching arguments
+ or otherwise fallback gracefully to a function call, and don't ICE during
+ compilation.
+ "-fno-builtin" option is used to enable calls to libc implementation of the
+ gcc builtins tested when not using __builtin_ prefix. */
+
+#include <fenv.h>
+
+int
+main ()
+{
+ int rsi = 0;
+ long rsl = 0;
+ short rss = 0;
+ char rsc = 0;
+
+ unsigned int rui = 0;
+ unsigned long rul = 0;
+ unsigned short rus = 0;
+ unsigned char ruc = 0;
+
+ int e = FE_DIVBYZERO;
+
+ __builtin_feclearexcept(e); // CALL
+ __builtin_feclearexcept(FE_ALL_EXCEPT); // CALL
+ __builtin_feclearexcept(FE_INVALID); // CALL
+ __builtin_feclearexcept(FE_INVALID | FE_INEXACT); // CALL
+
+ __builtin_feclearexcept(FE_INEXACT | FE_DIVBYZERO |
+ FE_UNDERFLOW | FE_OVERFLOW); // EXPAND
+ __builtin_feclearexcept(FE_INEXACT | FE_OVERFLOW); // EXPAND
+ __builtin_feclearexcept(FE_INEXACT); // EXPAND
+ __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ __builtin_feclearexcept(FE_UNDERFLOW); // EXPAND
+ __builtin_feclearexcept(FE_OVERFLOW); // EXPAND
+ __builtin_feclearexcept(0); // EXPAND
+
+ rsi = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ rsl = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ rss = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ rsc = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ rui = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ rul = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ rus = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+ ruc = __builtin_feclearexcept(FE_DIVBYZERO); // EXPAND
+
+
+ __builtin_feraiseexcept(e); // CALL
+ __builtin_feraiseexcept(FE_ALL_EXCEPT); // CALL
+ __builtin_feraiseexcept(FE_INVALID); // CALL
+ __builtin_feraiseexcept(FE_INVALID | FE_INEXACT); // CALL
+
+ __builtin_feraiseexcept(FE_INEXACT | FE_DIVBYZERO |
+ FE_UNDERFLOW | FE_OVERFLOW); // EXPAND
+ __builtin_feraiseexcept(FE_INEXACT | FE_OVERFLOW); // EXPAND
+ __builtin_feraiseexcept(FE_INEXACT); // EXPAND
+ __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ __builtin_feraiseexcept(FE_UNDERFLOW); // EXPAND
+ __builtin_feraiseexcept(FE_OVERFLOW); // EXPAND
+ __builtin_feraiseexcept(0); // EXPAND
+
+ rsi = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ rsl = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ rss = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ rsc = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ rui = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ rul = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ rus = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+ ruc = __builtin_feraiseexcept(FE_DIVBYZERO); // EXPAND
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-2.c b/gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-2.c
new file mode 100644
index 0000000..28c2a00
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-2.c
@@ -0,0 +1,91 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-lm -fno-builtin" } */
+
+/* This testcase ensures that the builtins are correctly expanded and match the
+ expected result.
+ "-fno-builtin" option is used to enable calls to libc implementation of the
+ gcc builtins tested when not using __builtin_ prefix.
+ The excepts parameter needs to be passed as constant to
+ __builtin_feclearexcept and __builtin_feraiseexcept because some bultins only
+ expand on constant input. */
+
+#include <fenv.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#define INFO(...) printf(__VA_ARGS__)
+#define FAIL(ret, raised, expected, excepts, excepts_str, func) \
+ printf("ERROR [l %d] testing %s (%x): %s returned %d." \
+ " Raised except bits %x, expecected %x\n", \
+ __LINE__, excepts_str, excepts, func, ret, raised, expected)
+#else
+void abort (void);
+#define INFO(...)
+#define FAIL(ret, raised, expected, excepts, excepts_str, func) abort()
+#endif
+
+#define TEST(excepts) \
+ do { \
+ int ret = 0; \
+ int raised = 0; \
+ \
+ INFO("test: %s (%x)\n", #excepts, excepts); \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ ret = __builtin_feraiseexcept(excepts); \
+ raised = fetestexcept(FE_ALL_EXCEPT); \
+ if (ret != 0 || raised != (excepts)) \
+ FAIL(ret, raised, excepts, excepts, #excepts, \
+ "__builtin_feraiseexcept"); \
+ \
+ feraiseexcept(FE_ALL_EXCEPT); \
+ ret = __builtin_feclearexcept(excepts); \
+ raised = fetestexcept(FE_ALL_EXCEPT); \
+ if (ret != 0 || raised != (FE_ALL_EXCEPT & ~(excepts))) \
+ FAIL(ret, raised, FE_ALL_EXCEPT & ~(excepts), excepts, #excepts, \
+ "__builtin_feclearexcept"); \
+ } while (0)
+
+int
+main ()
+{
+ TEST(0);
+ TEST(FE_ALL_EXCEPT);
+
+ TEST(FE_INVALID);
+ TEST(FE_DIVBYZERO);
+ TEST(FE_INEXACT);
+ TEST(FE_OVERFLOW);
+ TEST(FE_UNDERFLOW);
+
+ TEST(FE_INVALID | FE_DIVBYZERO);
+ TEST(FE_INVALID | FE_INEXACT);
+ TEST(FE_INVALID | FE_OVERFLOW);
+ TEST(FE_INVALID | FE_UNDERFLOW);
+ TEST(FE_DIVBYZERO | FE_INEXACT);
+ TEST(FE_DIVBYZERO | FE_OVERFLOW);
+ TEST(FE_DIVBYZERO | FE_UNDERFLOW);
+ TEST(FE_INEXACT | FE_OVERFLOW);
+ TEST(FE_INEXACT | FE_UNDERFLOW);
+ TEST(FE_OVERFLOW | FE_UNDERFLOW);
+
+ TEST(FE_INVALID | FE_DIVBYZERO | FE_INEXACT);
+ TEST(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
+ TEST(FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW);
+ TEST(FE_INVALID | FE_INEXACT | FE_OVERFLOW);
+ TEST(FE_INVALID | FE_INEXACT | FE_UNDERFLOW);
+ TEST(FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW);
+ TEST(FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW);
+ TEST(FE_DIVBYZERO | FE_INEXACT | FE_UNDERFLOW);
+ TEST(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
+ TEST(FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW);
+
+ TEST(FE_INVALID | FE_DIVBYZERO | FE_INEXACT | FE_UNDERFLOW);
+ TEST(FE_INVALID | FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW);
+ TEST(FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW);
+ TEST(FE_INVALID | FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW);
+ TEST(FE_DIVBYZERO | FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/builtin-fegetround.c b/gcc/testsuite/gcc.target/powerpc/builtin-fegetround.c
new file mode 100644
index 0000000..56ffc50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtin-fegetround.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-lm -fno-builtin" } */
+
+/* This testcase ensures that the builtins is correctly expanded and match the
+ expected result from the standard function.
+ "-fno-builtin" option is used to enable calls to libc implementation of the
+ gcc builtins tested when not using __builtin_ prefix. */
+
+#include <fenv.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#define FAIL(v, e) printf("ERROR, __builtin_fegetround() returned %d," \
+ " not the expecected value %d\n", v, e);
+#else
+void abort (void);
+#define FAIL(v, e) abort()
+#endif
+
+int
+main ()
+{
+ int i, rounding, expected;
+ const int rm[] = {FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD, FE_DOWNWARD};
+ for (i = 0; i < sizeof rm / sizeof rm[0]; i++)
+ {
+ fesetround(rm[i]);
+ rounding = __builtin_fegetround();
+ expected = fegetround();
+ if (rounding != expected)
+ FAIL(rounding, expected);
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr103702.c b/gcc/testsuite/gcc.target/powerpc/pr103702.c
new file mode 100644
index 0000000..585946f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr103702.c
@@ -0,0 +1,24 @@
+/* We don't have one powerpc.*_ok for Power6, use altivec_ok conservatively. */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-mdejagnu-cpu=power6 -O2 -ftree-loop-vectorize -fno-tree-scev-cprop" } */
+
+/* Verify there is no ICE. */
+
+unsigned short a, e;
+int *b, *d;
+int c;
+extern int fn2 ();
+void
+fn1 ()
+{
+ void *f;
+ for (;;)
+ {
+ fn2 ();
+ b = f;
+ e = 0;
+ for (; e < a; ++e)
+ b[e] = d[e * c];
+ }
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104239-1.c b/gcc/testsuite/gcc.target/powerpc/pr104239-1.c
new file mode 100644
index 0000000..eacdedd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104239-1.c
@@ -0,0 +1,10 @@
+/* PR target/104239 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8 -DNO_WARN_X86_INTRINSICS" } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+
+#if __has_include(<immintrin.h>)
+#include <immintrin.h>
+#endif
+
+int i;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104239-2.c b/gcc/testsuite/gcc.target/powerpc/pr104239-2.c
new file mode 100644
index 0000000..1bf316f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104239-2.c
@@ -0,0 +1,10 @@
+/* PR target/104239 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8 -DNO_WARN_X86_INTRINSICS" } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+
+#if __has_include(<x86gprintrin.h>)
+#include <x86gprintrin.h>
+#endif
+
+int i;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104239-3.c b/gcc/testsuite/gcc.target/powerpc/pr104239-3.c
new file mode 100644
index 0000000..6d64e5d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104239-3.c
@@ -0,0 +1,8 @@
+/* PR target/104239 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8 -DNO_WARN_X86_INTRINSICS -std=c89" } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+
+#include <x86intrin.h>
+
+int i;
diff --git a/gcc/testsuite/gfortran.dg/argument_checking_26.f90 b/gcc/testsuite/gfortran.dg/argument_checking_26.f90
new file mode 100644
index 0000000..2b765c5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/argument_checking_26.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! PR fortran/104212 - ICE in transformational_result
+! Contributed by G.Steinmetz
+
+program p
+ logical, parameter :: a(*,*) = reshape([.true.,.false.], shape=[1,2])
+ real, parameter :: r(*,*) = reshape([1.,2.], shape=[1,2])
+ print *, parity(a)
+ print *, parity(a, dim=1)
+ print *, parity(a, dim=[1]) ! { dg-error "must be a scalar" }
+ print *, norm2 (r)
+ print *, norm2 (r, dim=1)
+ print *, norm2 (r, dim=[1]) ! { dg-error "must be a scalar" }
+end
diff --git a/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90 b/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90
new file mode 100644
index 0000000..c83899d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90
@@ -0,0 +1,37 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original -fcoarray=lib" }
+!
+! PR 103970
+! Test case inspired by code submitted by Damian Rousson
+
+program main
+
+ implicit none
+
+ type foo_t
+ integer i
+ integer, allocatable :: j
+ end type
+
+ type(foo_t) foo
+ integer, parameter :: source_image = 1
+
+ if (this_image() == source_image) then
+ foo = foo_t(2,3)
+ else
+ allocate(foo%j)
+ end if
+ call co_broadcast(foo, source_image)
+
+ if ((foo%i /= 2) .or. (foo%j /= 3)) error stop 1
+ sync all
+
+end program
+
+! Wrong code generation produced too many temp descriptors
+! leading to stacked descriptors handed to the co_broadcast.
+! This lead to access to non exsitant memory in opencoarrays.
+! In single image mode just checking for reduced number of
+! descriptors is possible, i.e., execute always works.
+! { dg-final { scan-tree-dump-times "desc\\.\[0-9\]+" 12 "original" } }
+
diff --git a/gcc/testsuite/gfortran.dg/ieee/signaling_1.f90 b/gcc/testsuite/gfortran.dg/ieee/signaling_1.f90
index 94ece3a..19fee28 100644
--- a/gcc/testsuite/gfortran.dg/ieee/signaling_1.f90
+++ b/gcc/testsuite/gfortran.dg/ieee/signaling_1.f90
@@ -1,7 +1,6 @@
-! { dg-do run { xfail { { i?86-*-* x86_64-*-* } && ilp32 } } }
+! { dg-do run { target { ! ia32 } } }
! x87 / x86-32 ABI is unsuitable for signaling NaNs
!
-! { dg-require-effective-target issignaling } */
! { dg-additional-sources signaling_1_c.c }
! { dg-additional-options "-w" }
! The -w option is needed to make cc1 not report a warning for
@@ -40,7 +39,7 @@ program test
if (.not. ieee_unordered(x, x)) stop 105
if (.not. ieee_unordered(x, 1._c_float)) stop 106
- x = ieee_value(y, ieee_quiet_nan)
+ x = ieee_value(x, ieee_quiet_nan)
if (ieee_class(x) /= ieee_quiet_nan) stop 107
if (.not. ieee_is_nan(x)) stop 108
if (ieee_is_negative(x)) stop 109
@@ -80,7 +79,7 @@ program test
if (.not. ieee_unordered(z, z)) stop 305
if (.not. ieee_unordered(z, 1._c_long_double)) stop 306
- z = ieee_value(y, ieee_quiet_nan)
+ z = ieee_value(z, ieee_quiet_nan)
if (ieee_class(z) /= ieee_quiet_nan) stop 307
if (.not. ieee_is_nan(z)) stop 308
if (ieee_is_negative(z)) stop 309
diff --git a/gcc/testsuite/gfortran.dg/ieee/signaling_2.f90 b/gcc/testsuite/gfortran.dg/ieee/signaling_2.f90
index ff37ab6..03b04c7 100644
--- a/gcc/testsuite/gfortran.dg/ieee/signaling_2.f90
+++ b/gcc/testsuite/gfortran.dg/ieee/signaling_2.f90
@@ -1,7 +1,9 @@
-! { dg-do run { xfail { { i?86-*-* x86_64-*-* } && ilp32 } } }
+! { dg-do run { target { ! ia32 } } }
! x87 / x86-32 ABI is unsuitable for signaling NaNs
!
! { dg-require-effective-target issignaling } */
+! The companion C source needs access to the issignaling macro.
+!
! { dg-additional-sources signaling_2_c.c }
! { dg-additional-options "-w" }
! The -w option is needed to make cc1 not report a warning for
diff --git a/gcc/testsuite/gfortran.dg/ieee/signaling_3.f90 b/gcc/testsuite/gfortran.dg/ieee/signaling_3.f90
new file mode 100644
index 0000000..ff2585d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ieee/signaling_3.f90
@@ -0,0 +1,43 @@
+! { dg-do run { target { ! ia32 } } }
+! x87 / x86-32 ABI is unsuitable for signaling NaNs
+!
+program test
+ use, intrinsic :: iso_c_binding
+ use, intrinsic :: ieee_arithmetic
+ implicit none
+
+ real(kind=c_float) :: x
+ real(kind=c_double) :: y
+ real(kind=c_long_double) :: z
+
+ if (ieee_support_nan(x)) then
+ x = ieee_value(x, ieee_signaling_nan)
+ if (ieee_class(x) /= ieee_signaling_nan) stop 100
+ if (.not. ieee_is_nan(x)) stop 101
+
+ x = ieee_value(x, ieee_quiet_nan)
+ if (ieee_class(x) /= ieee_quiet_nan) stop 103
+ if (.not. ieee_is_nan(x)) stop 104
+ end if
+
+ if (ieee_support_nan(y)) then
+ y = ieee_value(y, ieee_signaling_nan)
+ if (ieee_class(y) /= ieee_signaling_nan) stop 100
+ if (.not. ieee_is_nan(y)) stop 101
+
+ y = ieee_value(y, ieee_quiet_nan)
+ if (ieee_class(y) /= ieee_quiet_nan) stop 103
+ if (.not. ieee_is_nan(y)) stop 104
+ end if
+
+ if (ieee_support_nan(z)) then
+ z = ieee_value(z, ieee_signaling_nan)
+ if (ieee_class(z) /= ieee_signaling_nan) stop 100
+ if (.not. ieee_is_nan(z)) stop 101
+
+ z = ieee_value(z, ieee_quiet_nan)
+ if (ieee_class(z) /= ieee_quiet_nan) stop 103
+ if (.not. ieee_is_nan(z)) stop 104
+ end if
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pr84784.f90 b/gcc/testsuite/gfortran.dg/pr84784.f90
new file mode 100644
index 0000000..3129b92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr84784.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdefault-integer-8" }
+! { dg-require-effective-target fortran_integer_16 }
+! PR fortran/84784 - ICEs: verify_gimple failed with -fdefault-integer-8
+
+ use iso_fortran_env, only : team_type, STAT_FAILED_IMAGE
+ implicit none
+ type(team_type) :: team
+ integer :: new_team
+ new_team = mod(this_image(),2)+1
+ form team (new_team,team)
+ change team (team)
+ if (team_number() /= new_team) STOP 1
+ end team
+ if (image_status (1) == STAT_FAILED_IMAGE) ERROR STOP "cannot recover"
+ if (runtime_popcnt(0_16) /= 0) STOP 2
+ if (runtime_poppar(1_16) /= 1) STOP 3
+contains
+ integer function runtime_popcnt (i)
+ integer(kind=16), intent(in) :: i
+ runtime_popcnt = popcnt(i)
+ end function
+ integer function runtime_poppar (i)
+ integer(kind=16), intent(in) :: i
+ runtime_poppar = poppar(i)
+ end function
+end
diff --git a/gcc/testsuite/gfortran.dg/transfer_check_6.f90 b/gcc/testsuite/gfortran.dg/transfer_check_6.f90
new file mode 100644
index 0000000..dffd091
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_check_6.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! PR fortran/104227 - ICE virtual memory exhausted
+! Contributed by G.Steinmetz
+
+program p
+ type t
+ end type
+ type(t) :: x(2)
+ print *, transfer(1, x) ! { dg-error "shall not have storage size 0" }
+ x = transfer(1, x) ! { dg-error "shall not have storage size 0" }
+end
diff --git a/gcc/testsuite/gfortran.dg/transfer_simplify_14.f90 b/gcc/testsuite/gfortran.dg/transfer_simplify_14.f90
new file mode 100644
index 0000000..dfb997d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_simplify_14.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR fortran/104128 - ICE in gfc_widechar_to_char
+! Contributed by G.Steinmetz
+
+program p
+ implicit none
+ integer, parameter :: k = 4
+ character(*), parameter :: a = 'abc'
+ character(*,kind=4), parameter :: b = 'abc'
+ character(2,kind=k), parameter :: s = k_"FG"
+ character(*,kind=1), parameter :: x = transfer (s, 'abcdefgh')
+ character(2,kind=k), parameter :: t = transfer (x, s)
+ character(2,kind=k) :: u = transfer (x, s)
+ logical, parameter :: l = (s == t)
+ print *, transfer (a , 4_'xy', size=2)
+ print *, transfer ('xyz', [b], size=2)
+ print *, s
+ print *, t
+ print *, u
+ if (.not. l) stop 1
+ if (t /= s) stop 2
+ if (u /= s) stop 3 ! not optimized away
+end
+
+! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 1 "original" } }
+! { dg-final { scan-tree-dump "_gfortran_stop_numeric \\(3, 0\\);" "original" } }
diff --git a/gcc/testsuite/gnat.dg/generic_comp.adb b/gcc/testsuite/gnat.dg/generic_comp.adb
new file mode 100644
index 0000000..8c7b16f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_comp.adb
@@ -0,0 +1,39 @@
+-- { dg-do run }
+
+procedure Generic_Comp is
+
+ generic
+ type Element_Type is private;
+ type Index_Type is (<>);
+ type Array_Type is array (Index_Type range <>) of Element_Type;
+ with function ">" (Left, Right : Element_Type) return Boolean is <>;
+ procedure Gen (Data: in out Array_Type);
+
+ procedure Gen (Data: in out Array_Type) is
+ begin
+ if not (Data'Length > 1)
+ or else not (Integer'(Data'Length) > 1)
+ or else not Standard.">" (Data'Length, 1)
+ or else not Standard.">" (Integer'(Data'Length), 1)
+ then
+ raise Program_Error;
+ end if;
+ end;
+
+ type My_Array is array (Positive range <>) of Integer;
+
+ function Less_Than (L, R : Integer) return Boolean is
+ begin
+ return L < R;
+ end;
+
+ procedure Chk_Down is new Gen (Element_Type => Integer,
+ Index_Type => Positive,
+ Array_Type => My_Array,
+ ">" => Less_Than);
+
+ Data : My_Array (1 .. 2);
+
+begin
+ Chk_Down (Data);
+end;
diff --git a/gcc/timevar.def b/gcc/timevar.def
index c239e8e..2dae5e1 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -307,6 +307,7 @@ DEFTIMEVAR (TV_TREE_UBSAN , "tree ubsan")
DEFTIMEVAR (TV_INITIALIZE_RTL , "initialize rtl")
DEFTIMEVAR (TV_GIMPLE_LADDRESS , "address lowering")
DEFTIMEVAR (TV_TREE_LOOP_IFCVT , "tree loop if-conversion")
+DEFTIMEVAR (TV_WARN_ACCESS , "access analysis")
/* Everything else in rest_of_compilation not included above. */
DEFTIMEVAR (TV_EARLY_LOCAL , "early local passes")
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 77178a6..efd1033 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -8915,10 +8915,6 @@ gimple_purge_dead_abnormal_call_edges (basic_block bb)
edge_iterator ei;
gimple *stmt = last_stmt (bb);
- if (!cfun->has_nonlocal_label
- && !cfun->calls_setjmp)
- return false;
-
if (stmt && stmt_can_make_abnormal_goto (stmt))
return false;
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 04c2095..d33095b 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -1915,14 +1915,23 @@ number_of_iterations_cond (class loop *loop,
}
/* If the new step of IV0 has changed sign or is of greater
magnitude then we do not know whether IV0 does overflow
- and thus the transform is not valid for code other than NE_EXPR */
+ and thus the transform is not valid for code other than NE_EXPR. */
else if (tree_int_cst_sign_bit (step) != tree_int_cst_sign_bit (iv0->step)
|| wi::gtu_p (wi::abs (wi::to_widest (step)),
wi::abs (wi::to_widest (iv0->step))))
{
- if (code != NE_EXPR)
+ if (POINTER_TYPE_P (type) && code != NE_EXPR)
+ /* For relational pointer compares we have further guarantees
+ that the pointers always point to the same object (or one
+ after it) and that objects do not cross the zero page. So
+ not only is the transform always valid for relational
+ pointer compares, we also know the resulting IV does not
+ overflow. */
+ ;
+ else if (code != NE_EXPR)
return false;
- iv0->no_overflow = false;
+ else
+ iv0->no_overflow = false;
}
iv0->step = step;
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 756ba6b..7ee5094 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -2768,7 +2768,49 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
vec<operand_entry *> *ops, tree exp, gimple_seq seq,
bool in_p, tree low, tree high, bool strict_overflow_p)
{
- operand_entry *oe = (*ops)[range->idx];
+ unsigned int idx = range->idx;
+ struct range_entry *swap_with = NULL;
+ basic_block rewrite_bb_first = NULL, rewrite_bb_last = NULL;
+ if (opcode == ERROR_MARK)
+ {
+ /* For inter-bb range test optimization, pick from the range tests
+ the one which is tested in the earliest condition (one dominating
+ the others), because otherwise there could be some UB (e.g. signed
+ overflow) in following bbs that we'd expose which wasn't there in
+ the original program. See PR104196. */
+ basic_block orig_range_bb = BASIC_BLOCK_FOR_FN (cfun, (*ops)[idx]->id);
+ basic_block range_bb = orig_range_bb;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ struct range_entry *this_range;
+ if (otherrange)
+ this_range = otherrange + i;
+ else
+ this_range = otherrangep[i];
+ operand_entry *oe = (*ops)[this_range->idx];
+ basic_block this_bb = BASIC_BLOCK_FOR_FN (cfun, oe->id);
+ if (range_bb != this_bb
+ && dominated_by_p (CDI_DOMINATORS, range_bb, this_bb))
+ {
+ swap_with = this_range;
+ range_bb = this_bb;
+ idx = this_range->idx;
+ }
+ }
+ /* If seq is non-NULL, it can contain statements that use SSA_NAMEs
+ only defined in later blocks. In this case we can't move the
+ merged comparison earlier, so instead check if there are any stmts
+ that might trigger signed integer overflow in between and rewrite
+ them. But only after we check if the optimization is possible. */
+ if (seq && swap_with)
+ {
+ rewrite_bb_first = range_bb;
+ rewrite_bb_last = orig_range_bb;
+ idx = range->idx;
+ swap_with = NULL;
+ }
+ }
+ operand_entry *oe = (*ops)[idx];
tree op = oe->op;
gimple *stmt = op ? SSA_NAME_DEF_STMT (op)
: last_stmt (BASIC_BLOCK_FOR_FN (cfun, oe->id));
@@ -2805,6 +2847,9 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
return false;
}
+ if (swap_with)
+ std::swap (range->idx, swap_with->idx);
+
if (strict_overflow_p && issue_strict_overflow_warning (wc))
warning_at (loc, OPT_Wstrict_overflow,
"assuming signed overflow does not occur "
@@ -2839,6 +2884,42 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
fprintf (dump_file, "\n");
}
+ /* In inter-bb range optimization mode, if we have a seq, we can't
+ move the merged comparison to the earliest bb from the comparisons
+ being replaced, so instead rewrite stmts that could trigger signed
+ integer overflow. */
+ for (basic_block bb = rewrite_bb_last;
+ bb != rewrite_bb_first; bb = single_pred (bb))
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ if (is_gimple_assign (stmt))
+ if (tree lhs = gimple_assign_lhs (stmt))
+ if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ || POINTER_TYPE_P (TREE_TYPE (lhs)))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)))
+ {
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ if (arith_code_with_undefined_signed_overflow (code))
+ {
+ gimple_stmt_iterator gsip = gsi;
+ gimple_stmt_iterator gsin = gsi;
+ gsi_prev (&gsip);
+ gsi_next (&gsin);
+ rewrite_to_defined_overflow (stmt, true);
+ unsigned uid = gimple_uid (stmt);
+ if (gsi_end_p (gsip))
+ gsip = gsi_after_labels (bb);
+ else
+ gsi_next (&gsip);
+ for (; gsi_stmt (gsip) != gsi_stmt (gsin);
+ gsi_next (&gsip))
+ gimple_set_uid (gsi_stmt (gsip), uid);
+ }
+ }
+ }
+
if (opcode == BIT_IOR_EXPR
|| (opcode == ERROR_MARK && oe->rank == BIT_IOR_EXPR))
tem = invert_truthvalue_loc (loc, tem);
@@ -4755,7 +4836,7 @@ maybe_optimize_range_tests (gimple *stmt)
&& (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
!= tcc_comparison)
&& !get_ops (rhs, code, &ops,
- loop_containing_stmt (stmt))
+ loop_containing_stmt (stmt))
&& has_single_use (rhs))
{
/* Otherwise, push the _234 range test itself. */
@@ -4792,6 +4873,8 @@ maybe_optimize_range_tests (gimple *stmt)
bb_ent.op = rhs;
}
bbinfo.safe_push (bb_ent);
+ for (unsigned int i = bb_ent.first_idx; i < bb_ent.last_idx; ++i)
+ ops[i]->id = bb->index;
continue;
}
else if (bb == last_bb)
@@ -4855,6 +4938,8 @@ maybe_optimize_range_tests (gimple *stmt)
bb_ent.last_idx = ops.length ();
}
bbinfo.safe_push (bb_ent);
+ for (unsigned int i = bb_ent.first_idx; i < bb_ent.last_idx; ++i)
+ ops[i]->id = bb->index;
if (bb == first_bb)
break;
}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 824ebb6..000a0f4 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -3444,7 +3444,9 @@ vectorizable_call (vec_info *vinfo,
{
if (slp_node)
for (i = 0; i < nargs; ++i)
- if (!vect_maybe_update_slp_op_vectype (slp_op[i], vectype_in))
+ if (!vect_maybe_update_slp_op_vectype (slp_op[i],
+ vectypes[i]
+ ? vectypes[i] : vectype_in))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
diff --git a/gcc/tree.cc b/gcc/tree.cc
index c4b3661..9d445b2 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -10492,7 +10492,7 @@ build_call_array_loc (location_t loc, tree return_type, tree fn,
/* Like build_call_array, but takes a vec. */
tree
-build_call_vec (tree return_type, tree fn, vec<tree, va_gc> *args)
+build_call_vec (tree return_type, tree fn, const vec<tree, va_gc> *args)
{
tree ret, t;
unsigned int ix;
diff --git a/gcc/tree.h b/gcc/tree.h
index 30bc53c..4c01d94 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4589,7 +4589,7 @@ extern tree build_call_valist (tree, tree, int, va_list);
#define build_call_array(T1,T2,N,T3)\
build_call_array_loc (UNKNOWN_LOCATION, T1, T2, N, T3)
extern tree build_call_array_loc (location_t, tree, tree, int, const tree *);
-extern tree build_call_vec (tree, tree, vec<tree, va_gc> *);
+extern tree build_call_vec (tree, tree, const vec<tree, va_gc> *);
extern tree build_call_expr_loc_array (location_t, tree, int, tree *);
extern tree build_call_expr_loc_vec (location_t, tree, vec<tree, va_gc> *);
extern tree build_call_expr_loc (location_t, tree, int, ...);