aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-06-11 13:03:29 +0200
committerMartin Liska <mliska@suse.cz>2021-06-11 13:03:29 +0200
commit845e0842307f248c7cc2b8fc713e48d1058ac86e (patch)
tree55e1676974e4c02e79c49755b84cd816125e7350
parent93e01322371f89c49ff0c1d2046de2654fdb797d (diff)
parent1fa991d1d74cb1ce96c48ede70ae0be7a9683ce3 (diff)
downloadgcc-845e0842307f248c7cc2b8fc713e48d1058ac86e.zip
gcc-845e0842307f248c7cc2b8fc713e48d1058ac86e.tar.gz
gcc-845e0842307f248c7cc2b8fc713e48d1058ac86e.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--contrib/ChangeLog5
-rwxr-xr-xcontrib/gcc-changelog/git_update_version.py4
-rw-r--r--gcc/ChangeLog116
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/config/h8300/extensions.md12
-rw-r--r--gcc/config/h8300/h8300.c4
-rw-r--r--gcc/config/i386/i386-expand.c300
-rw-r--r--gcc/config/i386/i386.md1
-rw-r--r--gcc/config/i386/mmx.md86
-rw-r--r--gcc/config/i386/sse.md1
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def2
-rw-r--r--gcc/config/rs6000/rs6000-call.c19
-rw-r--r--gcc/config/rs6000/rs6000.c6
-rw-r--r--gcc/config/rs6000/rs6000.md21
-rw-r--r--gcc/config/s390/vector.md2
-rw-r--r--gcc/coverage.c31
-rw-r--r--gcc/cp/ChangeLog24
-rw-r--r--gcc/cp/constexpr.c10
-rw-r--r--gcc/cp/constraint.cc9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/semantics.c82
-rw-r--r--gcc/d/ChangeLog13
-rw-r--r--gcc/d/d-frontend.cc33
-rw-r--r--gcc/d/d-tree.h1
-rw-r--r--gcc/d/typeinfo.cc38
-rw-r--r--gcc/doc/extend.texi4
-rw-r--r--gcc/doc/invoke.texi11
-rw-r--r--gcc/gimple-pretty-print.c7
-rw-r--r--gcc/gimple-ssa-evrp.c11
-rw-r--r--gcc/gimple.h18
-rw-r--r--gcc/gimplify.c5
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/ifcvt.c4
-rw-r--r--gcc/omp-builtins.def5
-rw-r--r--gcc/omp-expand.c19
-rw-r--r--gcc/omp-low.c9
-rw-r--r--gcc/sort.cc14
-rw-r--r--gcc/system.h1
-rw-r--r--gcc/testsuite/ChangeLog71
-rw-r--r--gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c4
-rw-r--r--gcc/testsuite/c-c++-common/goacc/finalize-1.c12
-rw-r--r--gcc/testsuite/c-c++-common/goacc/mdc-1.c19
-rw-r--r--gcc/testsuite/c-c++-common/goacc/mdc-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c8
-rw-r--r--gcc/testsuite/c-c++-common/goacc/struct-enter-exit-data-1.c4
-rw-r--r--gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C79
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C4
-rw-r--r--gcc/testsuite/g++.dg/goacc/mdc.C2
-rw-r--r--gcc/testsuite/g++.dg/opt/pr100852.C25
-rw-r--r--gcc/testsuite/g++.dg/template/ttp34.C14
-rw-r--r--gcc/testsuite/g++.dg/template/ttp34a.C14
-rw-r--r--gcc/testsuite/g++.dg/template/ttp34b.C14
-rw-r--r--gcc/testsuite/gcc.dg/pr100788.c13
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr101009.c17
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr56541.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101021-1.c35
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101021-2.c21
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mma-builtin-4.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mma-builtin-5.c24
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c23
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vcond-mixed-double.c41
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vcond-mixed-float.c41
-rw-r--r--gcc/testsuite/gdc.dg/pr100967.d11
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/attach-descriptor.f906
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/finalize-1.f12
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/mapping-tests-3.f902
-rw-r--r--gcc/toplev.c19
-rw-r--r--gcc/tree-data-ref.c10
-rw-r--r--gcc/tree-vect-slp.c7
-rw-r--r--gcc/value-query.cc24
-rw-r--r--gcc/value-query.h18
-rw-r--r--gcc/vec.h24
-rw-r--r--libgcc/ChangeLog5
-rw-r--r--libgcc/config/rs6000/quad-float128.h12
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/VERSION2
-rw-r--r--libgo/go/archive/zip/reader.go64
-rw-r--r--libgo/go/archive/zip/reader_test.go115
-rw-r--r--libgo/go/archive/zip/testdata/subdir.zipbin0 -> 428 bytes
-rw-r--r--libgo/go/cmd/go/internal/modcmd/download.go32
-rw-r--r--libgo/go/cmd/go/internal/modcmd/tidy.go2
-rw-r--r--libgo/go/cmd/go/internal/modload/buildlist.go30
-rw-r--r--libgo/go/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt2
-rw-r--r--libgo/go/cmd/go/testdata/script/mod_download.txt36
-rw-r--r--libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt10
-rw-r--r--libgo/go/cmd/go/testdata/script/mod_query.txt5
-rw-r--r--libgo/go/cmd/go/testdata/script/mod_readonly.txt8
-rw-r--r--libgo/go/go.mod2
-rw-r--r--libgo/go/golang.org/x/net/http/httpguts/httplex.go10
-rw-r--r--libgo/go/math/big/ratconv.go15
-rw-r--r--libgo/go/math/big/ratconv_test.go25
-rw-r--r--libgo/go/net/dnsclient_unix_test.go158
-rw-r--r--libgo/go/net/http/httputil/reverseproxy.go22
-rw-r--r--libgo/go/net/http/httputil/reverseproxy_test.go63
-rw-r--r--libgo/go/net/http/transport_test.go8
-rw-r--r--libgo/go/net/lookup.go111
-rw-r--r--libgo/go/os/signal/signal_test.go42
-rw-r--r--libgo/go/runtime/pprof/pprof_test.go3
-rw-r--r--libgo/go/runtime/proc.go26
-rw-r--r--libgo/go/runtime/runtime2.go7
-rw-r--r--libgo/go/runtime/sigqueue.go2
-rw-r--r--libgo/go/time/zoneinfo.go27
-rw-r--r--libgo/go/time/zoneinfo_read.go44
-rw-r--r--libgo/go/time/zoneinfo_test.go37
-rw-r--r--libgo/go/vendor/modules.txt2
-rw-r--r--libgomp/ChangeLog33
-rw-r--r--libgomp/libgomp.map6
-rw-r--r--libgomp/libgomp_g.h6
-rw-r--r--libgomp/oacc-mem.c172
-rw-r--r--libgomp/oacc-parallel.c58
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr100981-2.f902
116 files changed, 2283 insertions, 512 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index a07fc19..da7d4d5 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,8 @@
+2021-06-11 Martin Liska <mliska@suse.cz>
+
+ * gcc-changelog/git_update_version.py: Ignore commit that
+ violates rules and was somehow pushed.
+
2021-05-25 Jakub Jelinek <jakub@redhat.com>
* update-copyright.py: Add c++tools.
diff --git a/contrib/gcc-changelog/git_update_version.py b/contrib/gcc-changelog/git_update_version.py
index 0508f19..b97ca58 100755
--- a/contrib/gcc-changelog/git_update_version.py
+++ b/contrib/gcc-changelog/git_update_version.py
@@ -27,7 +27,9 @@ from git_repository import parse_git_revisions
current_timestamp = datetime.datetime.now().strftime('%Y%m%d\n')
# Skip the following commits, they cannot be correctly processed
-IGNORED_COMMITS = ('c2be82058fb40f3ae891c68d185ff53e07f14f45')
+IGNORED_COMMITS = (
+ 'c2be82058fb40f3ae891c68d185ff53e07f14f45',
+ '04a040d907a83af54e0a98bdba5bfabc0ef4f700')
def read_timestamp(path):
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fe95b63..b02695b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,119 @@
+2021-06-10 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/100984
+ * gimple-ssa-evrp.c (ssa_equiv_stack): Use auto_vec for
+ replacements table.
+ (ssa_equiv_stack::~ssa_equiv_stack): Remove.
+
+2021-06-11 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/rs6000/rs6000.md
+ (floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext): New
+ define_insn_and_split.
+
+2021-06-11 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (vect_build_slp_tree_2): Use stablesort
+ to sort operands of the associative chain.
+
+2021-06-11 Richard Biener <rguenther@suse.de>
+
+ * system.h (gcc_stablesort_r): Declare.
+ * sort.cc (gcc_sort_r): Support stable sort.
+ (gcc_stablesort_r): Define.
+ * vec.h (vec<>::stablesort): Add.
+
+2021-06-10 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/89021
+ * config/i386/i386-expand.c (ix86_split_mmx_punpck):
+ Handle V2SF mode. Emit SHUFPS to fixup unpack-high for V2SF mode.
+ (expand_vec_perm_blend): Handle 64bit modes for TARGET_SSE4_1.
+ (expand_vec_perm_pshufb): Handle 64bit modes for TARGET_SSSE3.
+ (expand_vec_perm_pblendv): Handle 64bit modes for TARGET_SSE4_1.
+ (expand_vec_perm_interleave2): Handle 64bit modes.
+ (expand_vec_perm_even_odd_pack): Handle V8QI mode.
+ (expand_vec_perm_even_odd_1): Ditto.
+ (ix86_vectorize_vec_perm_const): Ditto.
+ * config/i386/i386.md (UNSPEC_PSHUFB): Move from ...
+ * config/i386/sse.md: ... here.
+ * config/i386/mmx.md (*vec_interleave_lowv2sf):
+ New insn_and_split pattern.
+ (*vec_interleave_highv2sf): Ditto.
+ (mmx_pshufbv8qi3): New insn pattern.
+ (*mmx_pblendw): Ditto.
+
+2021-06-10 Peter Bergner <bergner@linux.ibm.com>
+
+ * config/rs6000/rs6000-builtin.def (build_pair): New built-in.
+ (build_acc): Likewise.
+ * config/rs6000/rs6000-call.c (mma_expand_builtin): Swap assemble
+ source operands in little-endian mode.
+ (rs6000_gimple_fold_mma_builtin): Handle VSX_BUILTIN_BUILD_PAIR.
+ (mma_init_builtins): Likewise.
+ * config/rs6000/rs6000.c (rs6000_split_multireg_move): Handle endianness
+ ordering for the MMA assemble and build source operands.
+ * doc/extend.texi (__builtin_vsx_build_acc, __builtin_mma_build_pair):
+ Document.
+ (__builtin_mma_assemble_acc, __builtin_mma_assemble_pair): Remove
+ documentation.
+
+2021-06-10 Jeff Law <jeffreyalaw@gmail.com>
+
+ * config/h8300/h8300.c (select_cc_mode): Handle MEM. Use
+ REG_P.
+ * config/h8300/extensions.md: Replace _clobber_flags patterns
+ with <cczn>.
+
+2021-06-10 Robin Dapp <rdapp@linux.ibm.com>
+
+ * config/s390/vector.md (vcond_mask_<mode><mode>): Change to
+ (vcond_mask_<mode><tointvec>): this.
+
+2021-06-10 Andrew Stubbs <ams@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * omp-builtins.def (BUILT_IN_GOACC_ENTER_EXIT_DATA): Split into...
+ (BUILT_IN_GOACC_ENTER_DATA, BUILT_IN_GOACC_EXIT_DATA): ... these.
+ * gimple.h (enum gf_mask): Split
+ 'GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA' into
+ 'GF_OMP_TARGET_KIND_OACC_ENTER_DATA' and
+ 'GF_OMP_TARGET_KIND_OACC_EXIT_DATA'.
+ (is_gimple_omp_oacc): Update.
+ * gimple-pretty-print.c (dump_gimple_omp_target): Likewise.
+ * gimplify.c (gimplify_omp_target_update): Likewise.
+ * omp-expand.c (expand_omp_target, build_omp_regions_1)
+ (omp_make_gimple_edges): Likewise.
+ * omp-low.c (check_omp_nesting_restrictions, lower_omp_target):
+ Likewise.
+
+2021-06-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-query.cc (value_query::value_on_edge): Rename name to
+ expr.
+ (range_query::range_on_edge): Same.
+ (range_query::value_of_expr): Same.
+ (range_query::value_on_edge): Same.
+ * value-query.h (class value_query): Same.
+ (class range_query): Same.
+
+2021-06-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/101003
+ * tree-vect-slp.c (vect_build_slp_tree_2): Appropriately
+ use the pattern stmt defs when linearizing a chain.
+
+2021-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/100852
+ * ifcvt.c (noce_get_alt_condition, noce_try_abs): Use
+ prev_nonnote_nondebug_insn instead of prev_nonnote_insn.
+
+2021-06-10 Clement Chigot <clement.chigot@atos.net>
+
+ * config/rs6000/aix71.h (ASM_CPU_SPEC): Add Power10 directive.
+ * config/rs6000/aix72.h (ASM_CPU_SPEC): Likewise.
+
2021-06-09 Andrew Pinski <apinski@marvell.com>
PR tree-optimization/100925
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 04de83c..702992b 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20210610
+20210611
diff --git a/gcc/common.opt b/gcc/common.opt
index 7f5fc39..a1353e0 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -826,6 +826,10 @@ Wcoverage-mismatch
Common Var(warn_coverage_mismatch) Init(1) Warning
Warn in case profiles in -fprofile-use do not match.
+Wcoverage-invalid-line-number
+Common Var(warn_coverage_invalid_linenum) Init(1) Warning
+Warn in case a function ends earlier than it begins due to an invalid linenum macros.
+
Wmissing-profile
Common Var(warn_missing_profile) Init(1) Warning
Warn in case profiles in -fprofile-use do not exist.
diff --git a/gcc/config/h8300/extensions.md b/gcc/config/h8300/extensions.md
index bc10179..74647c7 100644
--- a/gcc/config/h8300/extensions.md
+++ b/gcc/config/h8300/extensions.md
@@ -20,7 +20,7 @@
[(parallel [(set (match_dup 0) (zero_extend:HI (match_dup 1)))
(clobber (reg:CC CC_REG))])])
-(define_insn "*zero_extendqihi2_clobber_flags"
+(define_insn "*zero_extendqihi2<cczn>"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))
(clobber (reg:CC CC_REG))]
@@ -95,7 +95,7 @@
[(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
(clobber (reg:CC CC_REG))])])
-(define_insn "*zero_extendqisi2_h8sx_clobber_flags"
+(define_insn "*zero_extendqisi2_h8sx<cczn>"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -118,7 +118,7 @@
[(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
(clobber (reg:CC CC_REG))])])
-(define_insn "*zero_extendhisi2_clobber_flags"
+(define_insn "*zero_extendhisi2<cczn>"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -141,7 +141,7 @@
[(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
(clobber (reg:CC CC_REG))])])
-(define_insn "*extendqihi2_clobber_flags"
+(define_insn "*extendqihi2<cczn>"
[(set (match_operand:HI 0 "register_operand" "=r")
(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -176,7 +176,7 @@
[(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
(clobber (reg:CC CC_REG))])])
-(define_insn "*extendqisi2_h8sx_clobber_flags"
+(define_insn "*extendqisi2_h8sx<cczn>"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
@@ -199,7 +199,7 @@
[(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
(clobber (reg:CC CC_REG))])])
-(define_insn "*extendhisi2_clobber_flags"
+(define_insn "*extendhisi2<cczn>"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))]
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index ef947aa..1077a2b 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1950,7 +1950,9 @@ h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
|| GET_CODE (op0) == NEG || GET_CODE (op0) == AND
|| GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
|| GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
- || GET_CODE (op0) == REG || GET_CODE (op0) == MULT))
+ || GET_CODE (op0) == MULT
+ || GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND
+ || REG_P (op0) || MEM_P (op0)))
return CCZNmode;
return CCmode;
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index c3ce21b..2fa3a18 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -798,6 +798,15 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
GEN_INT (1), GEN_INT (5)));
break;
+ case E_V2SFmode:
+ sse_mode = V4SFmode;
+ double_sse_mode = V8SFmode;
+ mask = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4,
+ GEN_INT (0), GEN_INT (4),
+ GEN_INT (1), GEN_INT (5)));
+ break;
+
default:
gcc_unreachable ();
}
@@ -812,14 +821,26 @@ ix86_split_mmx_punpck (rtx operands[], bool high_p)
rtx insn = gen_rtx_SET (dest, op2);
emit_insn (insn);
+ /* Move bits 64:127 to bits 0:63. */
if (high_p)
{
- /* Move bits 64:127 to bits 0:63. */
- mask = gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (4, GEN_INT (2), GEN_INT (3),
- GEN_INT (0), GEN_INT (0)));
- dest = lowpart_subreg (V4SImode, dest, GET_MODE (dest));
- op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
+ if (sse_mode == V4SFmode)
+ {
+ mask = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4, GEN_INT (2), GEN_INT (3),
+ GEN_INT (4), GEN_INT (5)));
+ op2 = gen_rtx_VEC_CONCAT (V8SFmode, dest, dest);
+ op1 = gen_rtx_VEC_SELECT (V4SFmode, op2, mask);
+ }
+ else
+ {
+ mask = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4, GEN_INT (2), GEN_INT (3),
+ GEN_INT (0), GEN_INT (1)));
+ dest = lowpart_subreg (V4SImode, dest, GET_MODE (dest));
+ op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
+ }
+
insn = gen_rtx_SET (dest, op1);
emit_insn (insn);
}
@@ -17062,7 +17083,8 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
;
else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
;
- else if (TARGET_SSE4_1 && GET_MODE_SIZE (vmode) == 16)
+ else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 16
+ || GET_MODE_SIZE (vmode) == 8))
;
else
return false;
@@ -17095,6 +17117,7 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
case E_V8SFmode:
case E_V2DFmode:
case E_V4SFmode:
+ case E_V4HImode:
case E_V8HImode:
case E_V8SImode:
case E_V32HImode:
@@ -17111,6 +17134,12 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
vmode = V8HImode;
goto do_subreg;
+ case E_V2SImode:
+ for (i = 0; i < 2; ++i)
+ mask |= (d->perm[i] >= 2 ? 3 : 0) << (i * 2);
+ vmode = V4HImode;
+ goto do_subreg;
+
case E_V4SImode:
for (i = 0; i < 4; ++i)
mask |= (d->perm[i] >= 4 ? 3 : 0) << (i * 2);
@@ -17132,7 +17161,9 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
vperm = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm));
vperm = force_reg (vmode, vperm);
- if (GET_MODE_SIZE (vmode) == 16)
+ if (GET_MODE_SIZE (vmode) == 8)
+ emit_insn (gen_mmx_pblendvb64 (target, op0, op1, vperm));
+ else if (GET_MODE_SIZE (vmode) == 16)
emit_insn (gen_sse4_1_pblendvb (target, op0, op1, vperm));
else
emit_insn (gen_avx2_pblendvb (target, op0, op1, vperm));
@@ -17152,6 +17183,16 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
op1 = gen_lowpart (vmode, op1);
break;
+ case E_V8QImode:
+ for (i = 0; i < 8; i += 2)
+ if (d->perm[i] + 1 != d->perm[i + 1])
+ goto use_pblendvb;
+
+ for (i = 0; i < 4; ++i)
+ mask |= (d->perm[i * 2] >= 8) << i;
+ vmode = V4HImode;
+ goto do_subreg;
+
case E_V32QImode:
/* See if bytes move in pairs. If not, vpblendvb must be used. */
for (i = 0; i < 32; i += 2)
@@ -17313,6 +17354,59 @@ expand_vec_perm_vpermil (struct expand_vec_perm_d *d)
return true;
}
+/* For V*[QHS]Imode permutations, check if the same permutation
+ can't be performed in a 2x, 4x or 8x wider inner mode. */
+
+static bool
+canonicalize_vector_int_perm (const struct expand_vec_perm_d *d,
+ struct expand_vec_perm_d *nd)
+{
+ int i;
+ machine_mode mode = VOIDmode;
+
+ switch (d->vmode)
+ {
+ case E_V8QImode: mode = V4HImode; break;
+ case E_V16QImode: mode = V8HImode; break;
+ case E_V32QImode: mode = V16HImode; break;
+ case E_V64QImode: mode = V32HImode; break;
+ case E_V4HImode: mode = V2SImode; break;
+ case E_V8HImode: mode = V4SImode; break;
+ case E_V16HImode: mode = V8SImode; break;
+ case E_V32HImode: mode = V16SImode; break;
+ case E_V4SImode: mode = V2DImode; break;
+ case E_V8SImode: mode = V4DImode; break;
+ case E_V16SImode: mode = V8DImode; break;
+ default: return false;
+ }
+ for (i = 0; i < d->nelt; i += 2)
+ if ((d->perm[i] & 1) || d->perm[i + 1] != d->perm[i] + 1)
+ return false;
+ nd->vmode = mode;
+ nd->nelt = d->nelt / 2;
+ for (i = 0; i < nd->nelt; i++)
+ nd->perm[i] = d->perm[2 * i] / 2;
+ if (GET_MODE_INNER (mode) != DImode)
+ canonicalize_vector_int_perm (nd, nd);
+ if (nd != d)
+ {
+ nd->one_operand_p = d->one_operand_p;
+ nd->testing_p = d->testing_p;
+ if (d->op0 == d->op1)
+ nd->op0 = nd->op1 = gen_lowpart (nd->vmode, d->op0);
+ else
+ {
+ nd->op0 = gen_lowpart (nd->vmode, d->op0);
+ nd->op1 = gen_lowpart (nd->vmode, d->op1);
+ }
+ if (d->testing_p)
+ nd->target = gen_raw_REG (nd->vmode, LAST_VIRTUAL_REGISTER + 1);
+ else
+ nd->target = gen_reg_rtx (nd->vmode);
+ }
+ return true;
+}
+
/* Return true if permutation D can be performed as VMODE permutation
instead. */
@@ -17350,6 +17444,7 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
unsigned i, nelt, eltsz, mask;
unsigned char perm[64];
machine_mode vmode = V16QImode;
+ struct expand_vec_perm_d nd;
rtx rperm[64], vperm, target, op0, op1;
nelt = d->nelt;
@@ -17384,7 +17479,13 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
}
else
{
- if (GET_MODE_SIZE (d->vmode) == 16)
+ if (GET_MODE_SIZE (d->vmode) == 8)
+ {
+ if (!TARGET_SSSE3)
+ return false;
+ vmode = V8QImode;
+ }
+ else if (GET_MODE_SIZE (d->vmode) == 16)
{
if (!TARGET_SSSE3)
return false;
@@ -17492,6 +17593,10 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
return false;
}
+ /* Try to avoid variable permutation instruction. */
+ if (canonicalize_vector_int_perm (d, &nd) && expand_vec_perm_1 (&nd))
+ return false;
+
if (d->testing_p)
return true;
@@ -17506,12 +17611,12 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
eltsz = GET_MODE_UNIT_SIZE (d->vmode);
if (!d->one_operand_p)
mask = 2 * nelt - 1;
- else if (vmode == V16QImode)
- mask = nelt - 1;
else if (vmode == V64QImode)
mask = nelt / 4 - 1;
- else
+ else if (vmode == V32QImode)
mask = nelt / 2 - 1;
+ else
+ mask = nelt - 1;
for (i = 0; i < nelt; ++i)
{
@@ -17521,9 +17626,18 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
}
}
- vperm = gen_rtx_CONST_VECTOR (vmode,
- gen_rtvec_v (GET_MODE_NUNITS (vmode), rperm));
- vperm = force_reg (vmode, vperm);
+ machine_mode vpmode = vmode;
+
+ if (vmode == V8QImode)
+ {
+ for (i = nelt; i < 16; ++i)
+ rperm[i] = constm1_rtx;
+ vpmode = V16QImode;
+ }
+
+ vperm = gen_rtx_CONST_VECTOR (vpmode,
+ gen_rtvec_v (GET_MODE_NUNITS (vpmode), rperm));
+ vperm = force_reg (vpmode, vperm);
target = d->target;
if (d->vmode != vmode)
@@ -17531,7 +17645,9 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
op0 = gen_lowpart (vmode, d->op0);
if (d->one_operand_p)
{
- if (vmode == V16QImode)
+ if (vmode == V8QImode)
+ emit_insn (gen_mmx_pshufbv8qi3 (target, op0, vperm));
+ else if (vmode == V16QImode)
emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, vperm));
else if (vmode == V32QImode)
emit_insn (gen_avx2_pshufbv32qi3 (target, op0, vperm));
@@ -17559,57 +17675,6 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
return true;
}
-/* For V*[QHS]Imode permutations, check if the same permutation
- can't be performed in a 2x, 4x or 8x wider inner mode. */
-
-static bool
-canonicalize_vector_int_perm (const struct expand_vec_perm_d *d,
- struct expand_vec_perm_d *nd)
-{
- int i;
- machine_mode mode = VOIDmode;
-
- switch (d->vmode)
- {
- case E_V16QImode: mode = V8HImode; break;
- case E_V32QImode: mode = V16HImode; break;
- case E_V64QImode: mode = V32HImode; break;
- case E_V8HImode: mode = V4SImode; break;
- case E_V16HImode: mode = V8SImode; break;
- case E_V32HImode: mode = V16SImode; break;
- case E_V4SImode: mode = V2DImode; break;
- case E_V8SImode: mode = V4DImode; break;
- case E_V16SImode: mode = V8DImode; break;
- default: return false;
- }
- for (i = 0; i < d->nelt; i += 2)
- if ((d->perm[i] & 1) || d->perm[i + 1] != d->perm[i] + 1)
- return false;
- nd->vmode = mode;
- nd->nelt = d->nelt / 2;
- for (i = 0; i < nd->nelt; i++)
- nd->perm[i] = d->perm[2 * i] / 2;
- if (GET_MODE_INNER (mode) != DImode)
- canonicalize_vector_int_perm (nd, nd);
- if (nd != d)
- {
- nd->one_operand_p = d->one_operand_p;
- nd->testing_p = d->testing_p;
- if (d->op0 == d->op1)
- nd->op0 = nd->op1 = gen_lowpart (nd->vmode, d->op0);
- else
- {
- nd->op0 = gen_lowpart (nd->vmode, d->op0);
- nd->op1 = gen_lowpart (nd->vmode, d->op1);
- }
- if (d->testing_p)
- nd->target = gen_raw_REG (nd->vmode, LAST_VIRTUAL_REGISTER + 1);
- else
- nd->target = gen_reg_rtx (nd->vmode);
- }
- return true;
-}
-
/* Try to expand one-operand permutation with constant mask. */
static bool
@@ -18041,7 +18106,8 @@ expand_vec_perm_pblendv (struct expand_vec_perm_d *d)
;
else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
;
- else if (TARGET_SSE4_1 && GET_MODE_SIZE (vmode) == 16)
+ else if (TARGET_SSE4_1 && (GET_MODE_SIZE (vmode) == 8
+ || GET_MODE_SIZE (vmode) == 16))
;
else
return false;
@@ -18120,7 +18186,8 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
rtx_insn *seq;
bool ok, same_halves = false;
- if (GET_MODE_SIZE (d->vmode) == 16)
+ if (GET_MODE_SIZE (d->vmode) == 8
+ || GET_MODE_SIZE (d->vmode) == 16)
{
if (d->one_operand_p)
return false;
@@ -18155,7 +18222,44 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
memset (remap, 0xff, sizeof (remap));
dremap = *d;
- if (GET_MODE_SIZE (d->vmode) == 16)
+ if (GET_MODE_SIZE (d->vmode) == 8)
+ {
+ unsigned HOST_WIDE_INT h1, h2, h3, h4;
+
+ /* Split the two input vectors into 4 halves. */
+ h1 = (HOST_WIDE_INT_1U << nelt2) - 1;
+ h2 = h1 << nelt2;
+ h3 = h2 << nelt2;
+ h4 = h3 << nelt2;
+
+ /* If the elements from the low halves use interleave low,
+ and similarly for interleave high. */
+ if ((contents & (h1 | h3)) == contents)
+ {
+ /* punpckl* */
+ for (i = 0; i < nelt2; ++i)
+ {
+ remap[i] = i * 2;
+ remap[i + nelt] = i * 2 + 1;
+ dremap.perm[i * 2] = i;
+ dremap.perm[i * 2 + 1] = i + nelt;
+ }
+ }
+ else if ((contents & (h2 | h4)) == contents)
+ {
+ /* punpckh* */
+ for (i = 0; i < nelt2; ++i)
+ {
+ remap[i + nelt2] = i * 2;
+ remap[i + nelt + nelt2] = i * 2 + 1;
+ dremap.perm[i * 2] = i + nelt2;
+ dremap.perm[i * 2 + 1] = i + nelt + nelt2;
+ }
+ }
+ else
+ return false;
+ }
+ else if (GET_MODE_SIZE (d->vmode) == 16)
{
unsigned HOST_WIDE_INT h1, h2, h3, h4;
@@ -19328,9 +19432,9 @@ expand_vec_perm_vpshufb2_vpermq_even_odd (struct expand_vec_perm_d *d)
}
/* A subroutine of expand_vec_perm_even_odd_1. Implement extract-even
- and extract-odd permutations of two V16QI, V8HI, V16HI or V32QI operands
- with two "and" and "pack" or two "shift" and "pack" insns. We should
- have already failed all two instruction sequences. */
+ and extract-odd permutations of two V8QI, V8HI, V16QI, V16HI or V32QI
+ operands with two "and" and "pack" or two "shift" and "pack" insns.
+ We should have already failed all two instruction sequences. */
static bool
expand_vec_perm_even_odd_pack (struct expand_vec_perm_d *d)
@@ -19359,6 +19463,15 @@ expand_vec_perm_even_odd_pack (struct expand_vec_perm_d *d)
gen_pack = gen_sse4_1_packusdw;
gen_shift = gen_lshrv4si3;
break;
+ case E_V8QImode:
+ /* No check as all instructions are SSE2. */
+ c = 0xff;
+ s = 8;
+ half_mode = V4HImode;
+ gen_and = gen_andv4hi3;
+ gen_pack = gen_mmx_packuswb;
+ gen_shift = gen_lshrv4hi3;
+ break;
case E_V16QImode:
/* No check as all instructions are SSE2. */
c = 0xff;
@@ -19391,8 +19504,8 @@ expand_vec_perm_even_odd_pack (struct expand_vec_perm_d *d)
end_perm = true;
break;
default:
- /* Only V8HI, V16QI, V16HI and V32QI modes are more profitable than
- general shuffles. */
+ /* Only V8QI, V8HI, V16QI, V16HI and V32QI modes
+ are more profitable than general shuffles. */
return false;
}
@@ -19621,6 +19734,7 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd)
}
break;
+ case E_V8QImode:
case E_V16QImode:
return expand_vec_perm_even_odd_pack (d);
@@ -19786,6 +19900,41 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
/* These are always implementable using standard shuffle patterns. */
gcc_unreachable ();
+ case E_V8QImode:
+ /* These can be implemented via interleave. We save one insn by
+ stopping once we have promoted to V2SImode and then use pshufd. */
+ if (d->testing_p)
+ return true;
+ do
+ {
+ rtx dest;
+ rtx (*gen) (rtx, rtx, rtx)
+ = vmode == V8QImode ? gen_mmx_punpcklbw
+ : gen_mmx_punpcklwd;
+
+ if (elt >= nelt2)
+ {
+ gen = vmode == V8QImode ? gen_mmx_punpckhbw
+ : gen_mmx_punpckhwd;
+ elt -= nelt2;
+ }
+ nelt2 /= 2;
+
+ dest = gen_reg_rtx (vmode);
+ emit_insn (gen (dest, op0, op0));
+ vmode = get_mode_wider_vector (vmode);
+ op0 = gen_lowpart (vmode, dest);
+ }
+ while (vmode != V2SImode);
+
+ memset (perm2, elt, 2);
+ dest = gen_reg_rtx (V2SImode);
+ ok = expand_vselect (dest, op0, perm2, 2, d->testing_p);
+ gcc_assert (ok);
+ if (!d->testing_p)
+ emit_move_insn (d->target, gen_lowpart (d->vmode, dest));
+ return true;
+
case E_V8HImode:
case E_V16QImode:
/* These can be implemented via interleave. We save one insn by
@@ -20289,6 +20438,7 @@ ix86_vectorize_vec_perm_const (machine_mode vmode, rtx target, rtx op0,
case E_V2SFmode:
case E_V2SImode:
case E_V4HImode:
+ case E_V8QImode:
if (!TARGET_MMX_WITH_SSE)
return false;
break;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 5ff49ec..7743c61e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -119,6 +119,7 @@
UNSPEC_MASKMOV
UNSPEC_MOVMSK
UNSPEC_BLENDV
+ UNSPEC_PSHUFB
UNSPEC_RCP
UNSPEC_RSQRT
UNSPEC_PSADBW
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 0a17a54..f9e7d27 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1198,6 +1198,40 @@
(set_attr "prefix" "maybe_vex,orig")
(set_attr "mode" "V4SF")])
+(define_insn_and_split "*vec_interleave_lowv2sf"
+ [(set (match_operand:V2SF 0 "register_operand" "=x,v")
+ (vec_select:V2SF
+ (vec_concat:V4SF
+ (match_operand:V2SF 1 "register_operand" "0,v")
+ (match_operand:V2SF 2 "register_operand" "x,v"))
+ (parallel [(const_int 0) (const_int 2)])))]
+ "TARGET_MMX_WITH_SSE"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_mmx_punpck (operands, false); DONE;"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog")
+ (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "mode" "V4SF")])
+
+(define_insn_and_split "*vec_interleave_highv2sf"
+ [(set (match_operand:V2SF 0 "register_operand" "=x,v")
+ (vec_select:V2SF
+ (vec_concat:V4SF
+ (match_operand:V2SF 1 "register_operand" "0,v")
+ (match_operand:V2SF 2 "register_operand" "x,v"))
+ (parallel [(const_int 1) (const_int 3)])))]
+ "TARGET_MMX_WITH_SSE"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ "ix86_split_mmx_punpck (operands, true); DONE;"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "mode" "V4SF")])
+
(define_insn "*vec_dupv2sf"
[(set (match_operand:V2SF 0 "register_operand" "=y,Yv,x")
(vec_duplicate:V2SF
@@ -2415,7 +2449,7 @@
pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
@@ -2435,7 +2469,7 @@
packssdw\t{%2, %0|%0, %2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
@@ -2458,7 +2492,7 @@
punpckhbw\t{%2, %0|%0, %2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_punpck (operands, true); DONE;"
@@ -2481,7 +2515,7 @@
punpcklbw\t{%2, %0|%0, %k2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_punpck (operands, false); DONE;"
@@ -2502,7 +2536,7 @@
punpckhwd\t{%2, %0|%0, %2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_punpck (operands, true); DONE;"
@@ -2523,7 +2557,7 @@
punpcklwd\t{%2, %0|%0, %k2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_punpck (operands, false); DONE;"
@@ -2544,7 +2578,7 @@
punpckhdq\t{%2, %0|%0, %2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_punpck (operands, true); DONE;"
@@ -2565,7 +2599,7 @@
punpckldq\t{%2, %0|%0, %k2}
#
#"
- "TARGET_SSE2 && reload_completed
+ "&& reload_completed
&& SSE_REGNO_P (REGNO (operands[0]))"
[(const_int 0)]
"ix86_split_mmx_punpck (operands, false); DONE;"
@@ -2756,6 +2790,24 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
+(define_insn "mmx_pshufbv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=x,Yw")
+ (unspec:V8QI
+ [(match_operand:V8QI 1 "register_operand" "0,Yw")
+ (match_operand:V16QI 2 "vector_operand" "xBm,Ywm")]
+ UNSPEC_PSHUFB))]
+ "TARGET_SSSE3 && TARGET_MMX_WITH_SSE"
+ "@
+ pshufb\t{%2, %0|%0, %2}
+ vpshufb\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog1")
+ (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix_extra" "1")
+ (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "btver2_decode" "vector")
+ (set_attr "mode" "TI")])
+
(define_expand "mmx_pshufw"
[(match_operand:V4HI 0 "register_operand")
(match_operand:V4HI 1 "register_mmxmem_operand")
@@ -2828,6 +2880,24 @@
(set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
+(define_insn "*mmx_pblendw"
+ [(set (match_operand:V4HI 0 "register_operand" "=Yr,*x,x")
+ (vec_merge:V4HI
+ (match_operand:V4HI 2 "register_operand" "Yr,*x,x")
+ (match_operand:V4HI 1 "register_operand" "0,0,x")
+ (match_operand:SI 3 "const_0_to_63_operand" "n,n,n")))]
+ "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
+ "@
+ pblendw\t{%3, %2, %0|%0, %2, %3}
+ pblendw\t{%3, %2, %0|%0, %2, %3}
+ vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+ [(set_attr "isa" "noavx,noavx,avx")
+ (set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,orig,vex")
+ (set_attr "mode" "TI")])
+
;; Optimize V2SImode load from memory, swapping the elements and
;; storing back into the memory into DImode rotate of the memory by 32.
(define_split
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 2a34756..8403a07 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -28,7 +28,6 @@
UNSPEC_LDDQU
;; SSSE3
- UNSPEC_PSHUFB
UNSPEC_PSIGN
UNSPEC_PALIGNR
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index d55095b..231e7c9 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -3265,6 +3265,7 @@ BU_MMA_2 (DISASSEMBLE_ACC, "disassemble_acc", QUAD, mma_disassemble_acc)
BU_MMA_V2 (DISASSEMBLE_PAIR, "disassemble_pair", PAIR, vsx_disassemble_pair)
BU_COMPAT (VSX_BUILTIN_DISASSEMBLE_PAIR, "mma_disassemble_pair")
+BU_MMA_V3 (BUILD_PAIR, "build_pair", MISC, vsx_assemble_pair)
BU_MMA_V3 (ASSEMBLE_PAIR, "assemble_pair", MISC, vsx_assemble_pair)
BU_COMPAT (VSX_BUILTIN_ASSEMBLE_PAIR, "mma_assemble_pair")
BU_MMA_3 (XVBF16GER2, "xvbf16ger2", MISC, mma_xvbf16ger2)
@@ -3297,6 +3298,7 @@ BU_MMA_3 (XVI8GER4SPP, "xvi8ger4spp", QUAD, mma_xvi8ger4spp)
BU_MMA_3 (XVI16GER2PP, "xvi16ger2pp", QUAD, mma_xvi16ger2pp)
BU_MMA_3 (XVI16GER2SPP, "xvi16ger2spp", QUAD, mma_xvi16ger2spp)
+BU_MMA_5 (BUILD_ACC, "build_acc", MISC, mma_assemble_acc)
BU_MMA_5 (ASSEMBLE_ACC, "assemble_acc", MISC, mma_assemble_acc)
BU_MMA_5 (PMXVF32GER, "pmxvf32ger", MISC, mma_pmxvf32ger)
BU_MMA_5 (PMXVF64GER, "pmxvf64ger", PAIR, mma_pmxvf64ger)
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index b0b7f12..0ac6b6e 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -10244,12 +10244,23 @@ mma_expand_builtin (tree exp, rtx target, bool *expandedp)
pat = GEN_FCN (icode) (op[0], op[1]);
break;
case 3:
+ /* The ASSEMBLE builtin source operands are reversed in little-endian
+ mode, so reorder them. */
+ if (fcode == VSX_BUILTIN_ASSEMBLE_PAIR_INTERNAL && !WORDS_BIG_ENDIAN)
+ std::swap (op[1], op[2]);
pat = GEN_FCN (icode) (op[0], op[1], op[2]);
break;
case 4:
pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
break;
case 5:
+ /* The ASSEMBLE builtin source operands are reversed in little-endian
+ mode, so reorder them. */
+ if (fcode == MMA_BUILTIN_ASSEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN)
+ {
+ std::swap (op[1], op[4]);
+ std::swap (op[2], op[3]);
+ }
pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
break;
case 6:
@@ -11961,7 +11972,7 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi)
gcc_unreachable ();
}
- if (fncode == VSX_BUILTIN_ASSEMBLE_PAIR)
+ if (fncode == VSX_BUILTIN_BUILD_PAIR || fncode == VSX_BUILTIN_ASSEMBLE_PAIR)
lhs = make_ssa_name (vector_pair_type_node);
else
lhs = make_ssa_name (vector_quad_type_node);
@@ -14293,8 +14304,10 @@ mma_init_builtins (void)
machine_mode mode = insn_data[icode].operand[j].mode;
if (gimple_func && mode == XOmode)
op[nopnds++] = build_pointer_type (vector_quad_type_node);
- else if (gimple_func && mode == OOmode
- && d->code == VSX_BUILTIN_ASSEMBLE_PAIR)
+ else if (gimple_func
+ && mode == OOmode
+ && (d->code == VSX_BUILTIN_BUILD_PAIR
+ || d->code == VSX_BUILTIN_ASSEMBLE_PAIR))
op[nopnds++] = build_pointer_type (vector_pair_type_node);
else
/* MMA uses unsigned types. */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 75c2cc4..38f9281 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -16807,9 +16807,11 @@ rs6000_split_multireg_move (rtx dst, rtx src)
gcc_assert (VSX_REGNO_P (REGNO (dst)));
reg_mode = GET_MODE (XVECEXP (src, 0, 0));
- for (int i = 0; i < XVECLEN (src, 0); i++)
+ int nvecs = XVECLEN (src, 0);
+ for (int i = 0; i < nvecs; i++)
{
- rtx dst_i = gen_rtx_REG (reg_mode, reg + i);
+ int index = WORDS_BIG_ENDIAN ? i : nvecs - 1 - i;
+ rtx dst_i = gen_rtx_REG (reg_mode, reg + index);
emit_insn (gen_rtx_SET (dst_i, XVECEXP (src, 0, i)));
}
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 89c70f4..510dbff 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5524,6 +5524,27 @@
[(set_attr "length" "8")
(set_attr "type" "fpload")])
+(define_insn_and_split "floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext"
+ [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
+ (float:SFDF
+ (zero_extend:SI
+ (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z"))))
+ (clobber (match_scratch:DI 2 "=d,wa"))]
+ "TARGET_HARD_FLOAT && <SI_CONVERT_FP> && TARGET_P9_VECTOR
+ && TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+ "#"
+ "&& 1"
+ [(pc)]
+{
+ if (GET_CODE (operands[2]) == SCRATCH)
+ operands[2] = gen_reg_rtx (DImode);
+ emit_insn (gen_zero_extendhidi2 (operands[2], operands[1]));
+ emit_insn (gen_floatdi<SFDF:mode>2 (operands[0], operands[2]));
+ DONE;
+}
+ [(set_attr "length" "8")
+ (set_attr "type" "fpload")])
+
(define_insn "lfiwzx"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index c80d582..ab605b3 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -715,7 +715,7 @@
DONE;
})
-(define_expand "vcond_mask_<mode><mode>"
+(define_expand "vcond_mask_<mode><tointvec>"
[(set (match_operand:V 0 "register_operand" "")
(if_then_else:V
(eq (match_operand:<TOINTVEC> 3 "register_operand" "")
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 5a344cd..dfc8108 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -622,18 +622,16 @@ coverage_compute_cfg_checksum (struct function *fn)
int
coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
{
- expanded_location xloc;
- unsigned long offset;
-
/* We don't need to output .gcno file unless we're under -ftest-coverage
(e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
if (no_coverage || !bbg_file_name)
return 0;
- xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
+ expanded_location startloc
+ = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
/* Announce function */
- offset = gcov_write_tag (GCOV_TAG_FUNCTION);
+ unsigned long offset = gcov_write_tag (GCOV_TAG_FUNCTION);
if (param_profile_func_internal_id)
gcov_write_unsigned (current_function_funcdef_no + 1);
else
@@ -650,16 +648,27 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
&& !DECL_FUNCTION_VERSIONED (current_function_decl)
&& !DECL_LAMBDA_FUNCTION_P (current_function_decl));
- gcov_write_filename (xloc.file);
- gcov_write_unsigned (xloc.line);
- gcov_write_unsigned (xloc.column);
+ gcov_write_filename (startloc.file);
+ gcov_write_unsigned (startloc.line);
+ gcov_write_unsigned (startloc.column);
expanded_location endloc = expand_location (cfun->function_end_locus);
/* Function can start in a single file and end in another one. */
- int end_line = endloc.file == xloc.file ? endloc.line : xloc.line;
- int end_column = endloc.file == xloc.file ? endloc.column: xloc.column;
- gcc_assert (xloc.line <= end_line);
+ int end_line
+ = endloc.file == startloc.file ? endloc.line : startloc.line;
+ int end_column
+ = endloc.file == startloc.file ? endloc.column: startloc.column;
+
+ if (startloc.line > end_line)
+ {
+ warning_at (DECL_SOURCE_LOCATION (current_function_decl),
+ OPT_Wcoverage_invalid_line_number,
+ "function starts on a higher line number than it ends");
+ end_line = startloc.line;
+ end_column = startloc.column;
+ }
+
gcov_write_unsigned (end_line);
gcov_write_unsigned (end_column);
gcov_write_length (offset);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5a97fc8..ee5ef36 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,27 @@
+2021-06-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/100995
+ * constexpr.c (maybe_constexpr_fn): New.
+ * cp-tree.h (maybe_constexpr_fn): Declare.
+ * semantics.c (find_std_constant_evaluated_r): New.
+ (maybe_warn_for_constant_evaluated): New.
+ (finish_if_stmt_cond): Call it.
+
+2021-06-10 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/67829
+ * pt.c (unify) <case BOUND_TEMPLATE_TEMPLATE_PARM>: When
+ the TEMPLATE_DECL of a BOUND_TEMPLATE_TEMPLATE_PARM argument is
+ a template template parameter, adjust to the
+ TEMPLATE_TEMPLATE_PARAMETER before falling through.
+
+2021-06-10 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/100946
+ * constraint.cc (normalize_placeholder_type_constraints): When
+ normalizing a non-templated return-type-requirement, add a dummy
+ level to initial_parms.
+
2021-06-08 Marek Polacek <polacek@redhat.com>
PR c++/100065
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 297f207..01b0c42 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5121,6 +5121,16 @@ var_in_constexpr_fn (tree t)
&& DECL_DECLARED_CONSTEXPR_P (ctx));
}
+/* True if a function might be constexpr: either a function that was
+ declared constexpr, or a C++17 lambda op(). */
+
+bool
+maybe_constexpr_fn (tree t)
+{
+ return (DECL_DECLARED_CONSTEXPR_P (t)
+ || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t)));
+}
+
/* True if T was declared in a function that might be constexpr: either a
function that was declared constexpr, or a C++17 lambda op(). */
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 03ce8eb..74b16d2 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3065,6 +3065,15 @@ normalize_placeholder_type_constraints (tree t, bool diag)
scope for this placeholder type; use them as the initial template
parameters for normalization. */
tree initial_parms = TREE_PURPOSE (ci);
+
+ if (!initial_parms && TEMPLATE_TYPE_LEVEL (t) == 2)
+ /* This is a return-type-requirement of a non-templated requires-expression,
+ which are parsed under processing_template_decl == 1 and empty
+ current_template_parms; hence the 'auto' has level 2 and initial_parms
+ is empty. Fix up initial_parms to be consistent with the value of
+ processing_template_decl whence the 'auto' was created. */
+ initial_parms = build_tree_list (size_int (1), make_tree_vec (0));
+
/* The 'auto' itself is used as the first argument in its own constraints,
and its level is one greater than its template depth. So in order to
capture all used template parameters, we need to add an extra level of
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1b7e61..9ac8b52 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8244,6 +8244,7 @@ extern bool reduced_constant_expression_p (tree);
extern bool is_instantiation_of_constexpr (tree);
extern bool var_in_constexpr_fn (tree);
extern bool var_in_maybe_constexpr_fn (tree);
+extern bool maybe_constexpr_fn (tree);
extern void explain_invalid_constexpr_fn (tree);
extern vec<tree> cx_error_context (void);
extern tree fold_sizeof_expr (tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b0155a9..d87382d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23555,6 +23555,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return 1;
arg = TYPE_TI_TEMPLATE (arg);
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
+ /* If the template is a template template parameter, use the
+ TEMPLATE_TEMPLATE_PARM for matching. */
+ arg = TREE_TYPE (arg);
/* Fall through to deduce template name. */
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f506a23..384c54b 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -927,6 +927,71 @@ is_std_constant_evaluated_p (tree fn)
return name && id_equal (name, "is_constant_evaluated");
}
+/* Callback function for maybe_warn_for_constant_evaluated that looks
+ for calls to std::is_constant_evaluated in TP. */
+
+static tree
+find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
+{
+ tree t = *tp;
+
+ if (TYPE_P (t) || TREE_CONSTANT (t))
+ {
+ *walk_subtrees = false;
+ return NULL_TREE;
+ }
+
+ switch (TREE_CODE (t))
+ {
+ case CALL_EXPR:
+ if (is_std_constant_evaluated_p (t))
+ return t;
+ break;
+ case EXPR_STMT:
+ /* Don't warn in statement expressions. */
+ *walk_subtrees = false;
+ return NULL_TREE;
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* In certain contexts, std::is_constant_evaluated() is always true (for
+ instance, in a consteval function or in a constexpr if), or always false
+ (e.g., in a non-constexpr non-consteval function) so give the user a clue. */
+
+static void
+maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if)
+{
+ if (!warn_tautological_compare)
+ return;
+
+ /* Suppress warning for std::is_constant_evaluated if the conditional
+ comes from a macro. */
+ if (from_macro_expansion_at (EXPR_LOCATION (cond)))
+ return;
+
+ cond = cp_walk_tree_without_duplicates (&cond, find_std_constant_evaluated_r,
+ NULL);
+ if (cond)
+ {
+ if (constexpr_if)
+ warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+ "%<std::is_constant_evaluated%> always evaluates to "
+ "true in %<if constexpr%>");
+ else if (!maybe_constexpr_fn (current_function_decl))
+ warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+ "%<std::is_constant_evaluated%> always evaluates to "
+ "false in a non-%<constexpr%> function");
+ else if (DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
+ warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+ "%<std::is_constant_evaluated%> always evaluates to "
+ "true in a %<consteval%> function");
+ }
+}
+
/* Process the COND of an if-statement, which may be given by
IF_STMT. */
@@ -942,23 +1007,12 @@ finish_if_stmt_cond (tree cond, tree if_stmt)
converted to bool. */
&& TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
{
- /* if constexpr (std::is_constant_evaluated()) is always true,
- so give the user a clue. */
- if (warn_tautological_compare)
- {
- tree t = cond;
- if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == CALL_EXPR
- && is_std_constant_evaluated_p (t))
- warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
- "%qs always evaluates to true in %<if constexpr%>",
- "std::is_constant_evaluated");
- }
-
+ maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/true);
cond = instantiate_non_dependent_expr (cond);
cond = cxx_constant_value (cond, NULL_TREE);
}
+ else
+ maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false);
finish_cond (&IF_COND (if_stmt), cond);
add_stmt (if_stmt);
THEN_CLAUSE (if_stmt) = push_stmt_list ();
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 1b653f6..9ba56be 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,16 @@
+2021-06-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/100967
+ * d-frontend.cc (getTypeInfoType): Move TypeInfo checks to
+ check_typeinfo_type and call new function.
+ * d-tree.h (check_typeinfo_type): Declare.
+ * typeinfo.cc: Include dmd/scope.h.
+ (create_frontend_tinfo_types): Generate front-end types even if Object
+ is missing.
+ (build_typeinfo): Move TypeInfo checks to check_typeinfo_type and call
+ new function.
+ (check_typeinfo_type): New function.
+
2021-06-09 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/100964
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index 84c70f8..30fc6d43 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -185,39 +185,8 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
Type *
getTypeInfoType (Loc loc, Type *type, Scope *sc)
{
- if (!global.params.useTypeInfo)
- {
- /* Even when compiling without RTTI we should still be able to evaluate
- TypeInfo at compile-time, just not at run-time. */
- if (!sc || !(sc->flags & SCOPEctfe))
- {
- static int warned = 0;
-
- if (!warned)
- {
- error_at (make_location_t (loc),
- "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
- warned = 1;
- }
- }
- }
-
- if (Type::dtypeinfo == NULL
- || (Type::dtypeinfo->storage_class & STCtemp))
- {
- /* If TypeInfo has not been declared, warn about each location once. */
- static Loc warnloc;
-
- if (!loc.equals (warnloc))
- {
- error_at (make_location_t (loc),
- "%<object.TypeInfo%> could not be found, "
- "but is implicitly used");
- warnloc = loc;
- }
- }
-
gcc_assert (type->ty != Terror);
+ check_typeinfo_type (loc, sc);
create_typeinfo (type, sc ? sc->_module->importedFrom : NULL);
return type->vtinfo->type;
}
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index bb731a6..6ef9af2 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -670,6 +670,7 @@ extern tree layout_classinfo (ClassDeclaration *);
extern unsigned base_vtable_offset (ClassDeclaration *, BaseClass *);
extern tree get_typeinfo_decl (TypeInfoDeclaration *);
extern tree get_classinfo_decl (ClassDeclaration *);
+extern void check_typeinfo_type (const Loc &, Scope *);
extern tree build_typeinfo (const Loc &, Type *);
extern void create_typeinfo (Type *, Module *);
extern void create_tinfo_types (Module *);
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 503480b..9d6464d 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "dmd/identifier.h"
#include "dmd/module.h"
#include "dmd/mtype.h"
+#include "dmd/scope.h"
#include "dmd/template.h"
#include "dmd/target.h"
@@ -244,8 +245,8 @@ create_tinfo_types (Module *mod)
static void
create_frontend_tinfo_types (void)
{
- /* If there's no Object class defined, then neither can TypeInfo be. */
- if (object_module == NULL || ClassDeclaration::object == NULL)
+ /* If there's no object module, then neither can there be TypeInfo. */
+ if (object_module == NULL)
return;
/* Create all frontend TypeInfo classes declarations. We rely on all
@@ -1373,16 +1374,19 @@ get_classinfo_decl (ClassDeclaration *decl)
return decl->csym;
}
-/* Returns typeinfo reference for TYPE. */
+/* Performs sanity checks on the `object.TypeInfo' type, raising an error if
+ RTTI is disabled, or the type is missing. */
-tree
-build_typeinfo (const Loc &loc, Type *type)
+void
+check_typeinfo_type (const Loc &loc, Scope *sc)
{
if (!global.params.useTypeInfo)
{
static int warned = 0;
- if (!warned)
+ /* Even when compiling without RTTI we should still be able to evaluate
+ TypeInfo at compile-time, just not at run-time. */
+ if (!warned && (!sc || !(sc->flags & SCOPEctfe)))
{
error_at (make_location_t (loc),
"%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
@@ -1390,7 +1394,29 @@ build_typeinfo (const Loc &loc, Type *type)
}
}
+ if (Type::dtypeinfo == NULL
+ || (Type::dtypeinfo->storage_class & STCtemp))
+ {
+ /* If TypeInfo has not been declared, warn about each location once. */
+ static Loc warnloc;
+
+ if (!warnloc.equals (loc))
+ {
+ error_at (make_location_t (loc),
+ "%<object.TypeInfo%> could not be found, "
+ "but is implicitly used");
+ warnloc = loc;
+ }
+ }
+}
+
+/* Returns typeinfo reference for TYPE. */
+
+tree
+build_typeinfo (const Loc &loc, Type *type)
+{
gcc_assert (type->ty != Terror);
+ check_typeinfo_type (loc, NULL);
create_typeinfo (type, NULL);
return build_address (get_typeinfo_decl (type->vtinfo));
}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c24ecd7..408979b 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -20723,10 +20723,10 @@ void __builtin_mma_xxmtacc (__vector_quad *);
void __builtin_mma_xxmfacc (__vector_quad *);
void __builtin_mma_xxsetaccz (__vector_quad *);
-void __builtin_mma_assemble_acc (__vector_quad *, vec_t, vec_t, vec_t, vec_t);
+void __builtin_mma_build_acc (__vector_quad *, vec_t, vec_t, vec_t, vec_t);
void __builtin_mma_disassemble_acc (void *, __vector_quad *);
-void __builtin_vsx_assemble_pair (__vector_pair *, vec_t, vec_t);
+void __builtin_vsx_build_pair (__vector_pair *, vec_t, vec_t);
void __builtin_vsx_disassemble_pair (void *, __vector_pair *);
vec_t __builtin_vsx_xvcvspbf16 (vec_t);
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a9c97fc..1c4fbf2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5757,6 +5757,17 @@ poorly optimized code and is useful only in the
case of very minor changes such as bug fixes to an existing code-base.
Completely disabling the warning is not recommended.
+@item -Wno-coverage-invalid-line-number
+@opindex Wno-coverage-invalid-line-number
+@opindex Wcoverage-invalid-line-number
+Warn in case a function ends earlier than it begins due
+to an invalid linenum macros. The warning is emitted only
+with @option{--coverage} enabled.
+ By default, this warning is enabled and is treated as an
+error. @option{-Wno-coverage-invalid-line-number} can be used to disable the
+warning or @option{-Wno-error=coverage-invalid-line-number} can be used to
+disable the error.
+
@item -Wno-cpp
@r{(C, Objective-C, C++, Objective-C++ and Fortran only)}
@opindex Wno-cpp
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index c9c0a66..8be4041 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1697,8 +1697,11 @@ dump_gimple_omp_target (pretty_printer *buffer, const gomp_target *gs,
case GF_OMP_TARGET_KIND_OACC_UPDATE:
kind = " oacc_update";
break;
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
- kind = " oacc_enter_exit_data";
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ kind = " oacc_enter_data";
+ break;
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
+ kind = " oacc_exit_data";
break;
case GF_OMP_TARGET_KIND_OACC_DECLARE:
kind = " oacc_declare";
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 7e1cf51..eb8320a 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -53,7 +53,6 @@ class ssa_equiv_stack
{
public:
ssa_equiv_stack ();
- ~ssa_equiv_stack ();
void enter (basic_block);
void leave (basic_block);
void push_replacement (tree name, tree replacement);
@@ -61,19 +60,13 @@ public:
private:
auto_vec<std::pair <tree, tree>> m_stack;
- tree *m_replacements;
+ auto_vec<tree> m_replacements;
const std::pair <tree, tree> m_marker = std::make_pair (NULL, NULL);
};
ssa_equiv_stack::ssa_equiv_stack ()
{
- m_replacements = new tree[num_ssa_names] ();
-}
-
-ssa_equiv_stack::~ssa_equiv_stack ()
-{
- m_stack.release ();
- delete m_replacements;
+ m_replacements.safe_grow_cleared (num_ssa_names);
}
// Pushes a marker at the given point.
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 91b92b4..e7dc2a4 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -161,7 +161,7 @@ enum gf_mask {
GF_OMP_FOR_KIND_SIMD = 5,
GF_OMP_FOR_COMBINED = 1 << 3,
GF_OMP_FOR_COMBINED_INTO = 1 << 4,
- GF_OMP_TARGET_KIND_MASK = (1 << 4) - 1,
+ GF_OMP_TARGET_KIND_MASK = (1 << 5) - 1,
GF_OMP_TARGET_KIND_REGION = 0,
GF_OMP_TARGET_KIND_DATA = 1,
GF_OMP_TARGET_KIND_UPDATE = 2,
@@ -172,18 +172,19 @@ enum gf_mask {
GF_OMP_TARGET_KIND_OACC_SERIAL = 7,
GF_OMP_TARGET_KIND_OACC_DATA = 8,
GF_OMP_TARGET_KIND_OACC_UPDATE = 9,
- GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 10,
- GF_OMP_TARGET_KIND_OACC_DECLARE = 11,
- GF_OMP_TARGET_KIND_OACC_HOST_DATA = 12,
+ GF_OMP_TARGET_KIND_OACC_ENTER_DATA = 10,
+ GF_OMP_TARGET_KIND_OACC_EXIT_DATA = 11,
+ GF_OMP_TARGET_KIND_OACC_DECLARE = 12,
+ GF_OMP_TARGET_KIND_OACC_HOST_DATA = 13,
/* A 'GF_OMP_TARGET_KIND_OACC_PARALLEL' representing an OpenACC 'kernels'
decomposed part, parallelized. */
- GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED = 13,
+ GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED = 14,
/* A 'GF_OMP_TARGET_KIND_OACC_PARALLEL' representing an OpenACC 'kernels'
decomposed part, "gang-single". */
- GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE = 14,
+ GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE = 15,
/* A 'GF_OMP_TARGET_KIND_OACC_DATA' representing an OpenACC 'kernels'
decomposed parts' 'data' construct. */
- GF_OMP_TARGET_KIND_OACC_DATA_KERNELS = 15,
+ GF_OMP_TARGET_KIND_OACC_DATA_KERNELS = 16,
GF_OMP_TEAMS_HOST = 1 << 0,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
@@ -6525,7 +6526,8 @@ is_gimple_omp_oacc (const gimple *stmt)
case GF_OMP_TARGET_KIND_OACC_SERIAL:
case GF_OMP_TARGET_KIND_OACC_DATA:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 39f5b97..c96d611 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -13383,8 +13383,11 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
switch (TREE_CODE (expr))
{
case OACC_ENTER_DATA:
+ kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
+ ort = ORT_ACC;
+ break;
case OACC_EXIT_DATA:
- kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
+ kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
ort = ORT_ACC;
break;
case OACC_UPDATE:
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1f38c911..f16fb9f 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-5a801b15699cced5203af5c7339b375cd55ecbac
+bcafcb3c39530bb325514d6377747eb3127d1a03
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 6ee44cb..d086ce8 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2398,7 +2398,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
rtx_insn *prev_insn;
/* First, look to see if we put a constant in a register. */
- prev_insn = prev_nonnote_insn (if_info->cond_earliest);
+ prev_insn = prev_nonnote_nondebug_insn (if_info->cond_earliest);
if (prev_insn
&& BLOCK_FOR_INSN (prev_insn)
== BLOCK_FOR_INSN (if_info->cond_earliest)
@@ -2669,7 +2669,7 @@ noce_try_abs (struct noce_if_info *if_info)
if (REG_P (c))
{
rtx set;
- rtx_insn *insn = prev_nonnote_insn (earliest);
+ rtx_insn *insn = prev_nonnote_nondebug_insn (earliest);
if (insn
&& BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (earliest)
&& (set = single_set (insn))
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
index cfbf1e6..97964f8 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -35,7 +35,10 @@ DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_START, "GOACC_data_start",
BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_END, "GOACC_data_end",
BT_FN_VOID, ATTR_NOTHROW_LIST)
-DEF_GOACC_BUILTIN (BUILT_IN_GOACC_ENTER_EXIT_DATA, "GOACC_enter_exit_data",
+DEF_GOACC_BUILTIN (BUILT_IN_GOACC_ENTER_DATA, "GOACC_enter_data",
+ BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR,
+ ATTR_NOTHROW_LIST)
+DEF_GOACC_BUILTIN (BUILT_IN_GOACC_EXIT_DATA, "GOACC_exit_data",
BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR,
ATTR_NOTHROW_LIST)
DEF_GOACC_BUILTIN (BUILT_IN_GOACC_PARALLEL, "GOACC_parallel_keyed",
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index 0f843ba..f8b1558 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -9290,7 +9290,8 @@ expand_omp_target (struct omp_region *region)
case GF_OMP_TARGET_KIND_OACC_KERNELS:
case GF_OMP_TARGET_KIND_OACC_SERIAL:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
@@ -9574,8 +9575,11 @@ expand_omp_target (struct omp_region *region)
case GF_OMP_TARGET_KIND_OACC_UPDATE:
start_ix = BUILT_IN_GOACC_UPDATE;
break;
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
- start_ix = BUILT_IN_GOACC_ENTER_EXIT_DATA;
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ start_ix = BUILT_IN_GOACC_ENTER_DATA;
+ break;
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
+ start_ix = BUILT_IN_GOACC_EXIT_DATA;
break;
case GF_OMP_TARGET_KIND_OACC_DECLARE:
start_ix = BUILT_IN_GOACC_DECLARE;
@@ -9773,7 +9777,8 @@ expand_omp_target (struct omp_region *region)
oacc_set_fn_attrib (child_fn, clauses, &args);
tagging = true;
/* FALLTHRU */
- case BUILT_IN_GOACC_ENTER_EXIT_DATA:
+ case BUILT_IN_GOACC_ENTER_DATA:
+ case BUILT_IN_GOACC_EXIT_DATA:
case BUILT_IN_GOACC_UPDATE:
{
tree t_async = NULL_TREE;
@@ -10042,7 +10047,8 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
/* ..., other than for those stand-alone directives... */
region = NULL;
@@ -10299,7 +10305,8 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region,
case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
cur_region = cur_region->outer;
break;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 2d5cdf6..2cc2a18 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3646,8 +3646,10 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case GF_OMP_TARGET_KIND_OACC_SERIAL: stmt_name = "serial"; break;
case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
- stmt_name = "enter/exit data"; break;
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ stmt_name = "enter data"; break;
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
+ stmt_name = "exit data"; break;
case GF_OMP_TARGET_KIND_OACC_DECLARE: stmt_name = "declare"; break;
case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data";
break;
@@ -12194,7 +12196,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
case GF_OMP_TARGET_KIND_OACC_KERNELS:
case GF_OMP_TARGET_KIND_OACC_SERIAL:
case GF_OMP_TARGET_KIND_OACC_UPDATE:
- case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
+ case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
+ case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED:
case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE:
diff --git a/gcc/sort.cc b/gcc/sort.cc
index fe499b5..1c83c62 100644
--- a/gcc/sort.cc
+++ b/gcc/sort.cc
@@ -277,8 +277,12 @@ gcc_sort_r (void *vbase, size_t n, size_t size, sort_r_cmp_fn *cmp, void *data)
{
if (n < 2)
return;
+ size_t nlim = 5;
+ bool stable = (ssize_t) size < 0;
+ if (stable)
+ nlim = 3, size = ~size;
char *base = (char *)vbase;
- sort_r_ctx c = {data, cmp, base, n, size, 5};
+ sort_r_ctx c = {data, cmp, base, n, size, nlim};
long long scratch[32];
size_t bufsz = (n / 2) * size;
void *buf = bufsz <= sizeof scratch ? scratch : xmalloc (bufsz);
@@ -296,3 +300,11 @@ gcc_stablesort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
{
gcc_qsort (vbase, n, ~size, cmp);
}
+
+/* Stable sort, signature-compatible to Glibc qsort_r. */
+void
+gcc_stablesort_r (void *vbase, size_t n, size_t size, sort_r_cmp_fn *cmp,
+ void *data)
+{
+ gcc_sort_r (vbase, n, ~size, cmp, data);
+}
diff --git a/gcc/system.h b/gcc/system.h
index 3c85626..adde3e2 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1250,6 +1250,7 @@ void gcc_sort_r (void *, size_t, size_t, sort_r_cmp_fn *, void *);
void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
void gcc_stablesort (void *, size_t, size_t,
int (*)(const void *, const void *));
+void gcc_stablesort_r (void *, size_t, size_t, sort_r_cmp_fn *, void *data);
/* Redirect four-argument qsort calls to gcc_qsort; one-argument invocations
correspond to vec::qsort, and use C qsort internally. */
#define PP_5th(a1, a2, a3, a4, a5, ...) a5
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9e31d68..9c4c17b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,74 @@
+2021-06-11 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.target/powerpc/p9-fpcvt-3.c: New test.
+
+2021-06-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/100995
+ * g++.dg/cpp2a/is-constant-evaluated9.C: Add dg-warning.
+ * g++.dg/cpp2a/is-constant-evaluated12.C: New test.
+
+2021-06-10 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/67829
+ * g++.dg/template/ttp34.C: New test.
+ * g++.dg/template/ttp34a.C: New test.
+ * g++.dg/template/ttp34b.C: New test.
+
+2021-06-10 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/100946
+ * g++.dg/cpp2a/concepts-return-req3.C: New test.
+
+2021-06-10 Peter Bergner <bergner@linux.ibm.com>
+
+ * gcc.target/powerpc/mma-builtin-4.c (__builtin_vsx_build_pair): Add
+ tests. Update expected counts.
+ * gcc.target/powerpc/mma-builtin-5.c (__builtin_mma_build_acc): Add
+ tests. Update expected counts.
+
+2021-06-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/100967
+ * gdc.dg/pr100967.d: New test.
+
+2021-06-10 Robin Dapp <rdapp@linux.ibm.com>
+
+ * gcc.target/s390/vector/vcond-mixed-double.c: New test.
+ * gcc.target/s390/vector/vcond-mixed-float.c: New test.
+
+2021-06-10 Robin Dapp <rdapp@linux.ibm.com>
+
+ * gcc.dg/vect/pr56541.c: Fix target selector.
+
+2021-06-10 Andrew Stubbs <ams@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc-gomp/nesting-fail-1.c: Adjust patterns.
+ * c-c++-common/goacc/finalize-1.c: Likewise.
+ * c-c++-common/goacc/mdc-1.c: Likewise.
+ * c-c++-common/goacc/nesting-fail-1.c: Likewise.
+ * c-c++-common/goacc/struct-enter-exit-data-1.c: Likewise.
+ * gfortran.dg/goacc/attach-descriptor.f90: Likewise.
+ * gfortran.dg/goacc/finalize-1.f: Likewise.
+ * gfortran.dg/goacc/mapping-tests-3.f90: Likewise.
+
+2021-06-10 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-c++-common/goacc/mdc-1.c: Fix '#pragma acc acc [...]' typo.
+ * c-c++-common/goacc/mdc-2.c: Likewise.
+ * g++.dg/goacc/mdc.C: Likewise.
+
+2021-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/cpp2a/feat-cxx2a.C: Uncomment __cpp_consteval test.
+ * g++.dg/cpp23/feat-cxx2b.C: Likewise.
+
+2021-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/100852
+ * g++.dg/opt/pr100852.C: New test.
+
2021-06-09 Andrew Pinski <apinski@marvell.com>
* g++.dg/torture/pr100925.C: New test.
diff --git a/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c b/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c
index 1a33242..ddbd247 100644
--- a/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c
+++ b/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c
@@ -162,8 +162,8 @@ f_omp (void)
#pragma acc data /* { dg-error "OpenACC .data. construct inside of OpenMP .target. region" } */
;
#pragma acc update host(i) /* { dg-error "OpenACC .update. construct inside of OpenMP .target. region" } */
-#pragma acc enter data copyin(i) /* { dg-error "OpenACC .enter/exit data. construct inside of OpenMP .target. region" } */
-#pragma acc exit data delete(i) /* { dg-error "OpenACC .enter/exit data. construct inside of OpenMP .target. region" } */
+#pragma acc enter data copyin(i) /* { dg-error "OpenACC .enter data. construct inside of OpenMP .target. region" } */
+#pragma acc exit data delete(i) /* { dg-error "OpenACC .exit data. construct inside of OpenMP .target. region" } */
#pragma acc loop /* { dg-error "loop directive must be associated with an OpenACC compute region" } */
for (i = 0; i < 2; ++i)
;
diff --git a/gcc/testsuite/c-c++-common/goacc/finalize-1.c b/gcc/testsuite/c-c++-common/goacc/finalize-1.c
index 3d64b2e..54bf1b7 100644
--- a/gcc/testsuite/c-c++-common/goacc/finalize-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/finalize-1.c
@@ -13,25 +13,25 @@ void f ()
{
#pragma acc exit data delete (del_r)
/* { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(release:del_r\\);$" 1 "original" } }
- { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(release:del_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } } */
+ { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(release:del_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } } */
#pragma acc exit data finalize delete (del_f)
/* { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(release:del_f\\) finalize;$" 1 "original" } }
- { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(delete:del_f \\\[len: \[0-9\]+\\\]\\) finalize$" 1 "gimple" } } */
+ { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(delete:del_f \\\[len: \[0-9\]+\\\]\\) finalize$" 1 "gimple" } } */
#pragma acc exit data finalize delete (del_f_p[2:5])
/* { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(release:\\*\\(del_f_p \\+ 2\\) \\\[len: 5\\\]\\) map\\(firstprivate:del_f_p \\\[pointer assign, bias: 2\\\]\\) finalize;$" 1 "original" } }
- { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(delete:\[^ \]+ \\\[len: 5\\\]\\) finalize$" 1 "gimple" } } */
+ { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(delete:\[^ \]+ \\\[len: 5\\\]\\) finalize$" 1 "gimple" } } */
#pragma acc exit data copyout (cpo_r)
/* { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(from:cpo_r\\);$" 1 "original" } }
- { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(from:cpo_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } } */
+ { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(from:cpo_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } } */
#pragma acc exit data copyout (cpo_f) finalize
/* { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data finalize map\\(from:cpo_f\\);$" 1 "original" } }
- { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data finalize map\\(force_from:cpo_f \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } } */
+ { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data finalize map\\(force_from:cpo_f \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } } */
#pragma acc exit data copyout (cpo_f_p[4:10]) finalize
/* { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data finalize map\\(from:\\*\\(cpo_f_p \\+ 4\\) \\\[len: 10\\\]\\) map\\(firstprivate:cpo_f_p \\\[pointer assign, bias: 4\\\]\\);$" 1 "original" } }
- { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data finalize map\\(force_from:\[^ \]+ \\\[len: 10\\\]\\)$" 1 "gimple" } } */
+ { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data finalize map\\(force_from:\[^ \]+ \\\[len: 10\\\]\\)$" 1 "gimple" } } */
}
diff --git a/gcc/testsuite/c-c++-common/goacc/mdc-1.c b/gcc/testsuite/c-c++-common/goacc/mdc-1.c
index 337c1f7..c2b8dc6 100644
--- a/gcc/testsuite/c-c++-common/goacc/mdc-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/mdc-1.c
@@ -30,7 +30,7 @@ t1 ()
}
#pragma acc enter data copyin(a)
-#pragma acc acc enter data attach(s.e)
+#pragma acc enter data attach(s.e)
#pragma acc exit data detach(s.e)
#pragma acc data attach(s.e)
@@ -43,14 +43,15 @@ t1 ()
}
}
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.to:s .len: 32.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_data map.to:s .len: 32.." 1 "omplower" } } */
/* { dg-final { scan-tree-dump-times "pragma omp target oacc_data map.tofrom:.z .len: 40.. map.struct:s .len: 1.. map.alloc:s.a .len: 8.. map.tofrom:._1 .len: 40.. map.attach:s.a .bias: 0.." 1 "omplower" } } */
/* { dg-final { scan-tree-dump-times "pragma omp target oacc_parallel map.attach:s.e .bias: 0.. map.tofrom:s .len: 32" 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.attach:a .bias: 0.." 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.detach:a .bias: 0.." 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.to:a .len: 8.." 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.detach:s.e .bias: 0.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_data map.attach:a .bias: 0.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_exit_data map.detach:a .bias: 0.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_data map.to:a .len: 8.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_data map.attach:s.e .bias: 0.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_exit_data map.detach:s.e .bias: 0.." 1 "omplower" } } */
/* { dg-final { scan-tree-dump-times "pragma omp target oacc_data map.attach:s.e .bias: 0.." 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data map.release:a .len: 8.." 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data finalize map.force_detach:a .bias: 0.." 1 "omplower" } } */
-/* { dg-final { scan-tree-dump-times "pragma omp target oacc_enter_exit_data finalize map.force_detach:s.a .bias: 0.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_exit_data map.release:a .len: 8.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_exit_data finalize map.force_detach:a .bias: 0.." 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "pragma omp target oacc_exit_data finalize map.force_detach:s.a .bias: 0.." 1 "omplower" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/mdc-2.c b/gcc/testsuite/c-c++-common/goacc/mdc-2.c
index fae8667..df3ce54 100644
--- a/gcc/testsuite/c-c++-common/goacc/mdc-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/mdc-2.c
@@ -39,7 +39,7 @@ t1 ()
#pragma acc enter data attach(z[3]) /* { dg-error "expected pointer in .attach. clause" } */
#pragma acc exit data detach(z[3]) /* { dg-error "expected pointer in .detach. clause" } */
-#pragma acc acc enter data attach(s.e)
+#pragma acc enter data attach(s.e)
#pragma acc exit data detach(s.e) attach(z) /* { dg-error ".attach. is not valid for" } */
#pragma acc data attach(s.e)
diff --git a/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c b/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c
index 93a9111..5cfb327 100644
--- a/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c
@@ -14,8 +14,8 @@ f_acc_parallel (void)
#pragma acc data /* { dg-error ".data. construct inside of .parallel. region" } */
;
#pragma acc update host(i) /* { dg-error ".update. construct inside of .parallel. region" } */
-#pragma acc enter data copyin(i) /* { dg-error ".enter/exit data. construct inside of .parallel. region" } */
-#pragma acc exit data delete(i) /* { dg-error ".enter/exit data. construct inside of .parallel. region" } */
+#pragma acc enter data copyin(i) /* { dg-error ".enter data. construct inside of .parallel. region" } */
+#pragma acc exit data delete(i) /* { dg-error ".exit data. construct inside of .parallel. region" } */
}
}
@@ -33,8 +33,8 @@ f_acc_kernels (void)
#pragma acc data /* { dg-error ".data. construct inside of .kernels. region" } */
;
#pragma acc update host(i) /* { dg-error ".update. construct inside of .kernels. region" } */
-#pragma acc enter data copyin(i) /* { dg-error ".enter/exit data. construct inside of .kernels. region" } */
-#pragma acc exit data delete(i) /* { dg-error ".enter/exit data. construct inside of .kernels. region" } */
+#pragma acc enter data copyin(i) /* { dg-error ".enter data. construct inside of .kernels. region" } */
+#pragma acc exit data delete(i) /* { dg-error ".exit data. construct inside of .kernels. region" } */
}
}
diff --git a/gcc/testsuite/c-c++-common/goacc/struct-enter-exit-data-1.c b/gcc/testsuite/c-c++-common/goacc/struct-enter-exit-data-1.c
index df405e4..9e5d3f2 100644
--- a/gcc/testsuite/c-c++-common/goacc/struct-enter-exit-data-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/struct-enter-exit-data-1.c
@@ -20,8 +20,8 @@ test (int *b, int *c, int *e)
struct str s = { .a = 0, .b = b, .c = c, .d = 0, .e = e, .f = 0 };
#pragma acc enter data copyin(s.a, s.b[0:N], s.c[0:N] /* , s.d */ /* , s.e[0:N] */, s.f)
- /* { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_enter_exit_data map\(struct:s \[len: 4\]\) map\(to:s.a \[len: [0-9]+\]\) map\(alloc:s.b \[len: [0-9]+\]\) map\(alloc:s.c \[len: [0-9]+\]\) map\(to:s.f \[len: [0-9]+\]\) map\(to:\*[_0-9]+ \[len: [0-9]+\]\) map\(attach:s.b \[bias: 0\]\) map\(to:\*[_0-9]+ \[len: [0-9]+\]\) map\(attach:s.c \[bias: 0\]\)$} gimple } } */
+ /* { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_enter_data map\(struct:s \[len: 4\]\) map\(to:s.a \[len: [0-9]+\]\) map\(alloc:s.b \[len: [0-9]+\]\) map\(alloc:s.c \[len: [0-9]+\]\) map\(to:s.f \[len: [0-9]+\]\) map\(to:\*[_0-9]+ \[len: [0-9]+\]\) map\(attach:s.b \[bias: 0\]\) map\(to:\*[_0-9]+ \[len: [0-9]+\]\) map\(attach:s.c \[bias: 0\]\)$} gimple } } */
#pragma acc exit data copyout(s.a, s.b[0:N], s.c[0:N] /* , s.d */ /* , s.e[0:N] */, s.f)
- /* { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_enter_exit_data map\(from:s.a \[len: [0-9]+\]\) map\(release:s.b \[len: [0-9]+\]\) map\(release:s.c \[len: [0-9]+\]\) map\(from:s.f \[len: [0-9]+\]\) map\(from:\*[_0-9]+ \[len: [0-9]+\]\) map\(detach:s.b \[bias: 0\]\) map\(from:\*[_0-9]+ \[len: [0-9]+\]\) map\(detach:s.c \[bias: 0\]\)$} gimple } } */
+ /* { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_exit_data map\(from:s.a \[len: [0-9]+\]\) map\(release:s.b \[len: [0-9]+\]\) map\(release:s.c \[len: [0-9]+\]\) map\(from:s.f \[len: [0-9]+\]\) map\(from:\*[_0-9]+ \[len: [0-9]+\]\) map\(detach:s.b \[bias: 0\]\) map\(from:\*[_0-9]+ \[len: [0-9]+\]\) map\(detach:s.c \[bias: 0\]\)$} gimple } } */
}
diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
index 4a342e9..283a8ba 100644
--- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
+++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
@@ -520,13 +520,11 @@
# error "__cpp_constexpr_in_decltype != 201711"
#endif
-/* Not supported fully yet:
#ifndef __cpp_consteval
# error "__cpp_consteval"
#elif __cpp_consteval != 201811
# error "__cpp_consteval != 201811"
#endif
-*/
#ifndef __cpp_concepts
# error "__cpp_concepts"
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C
new file mode 100644
index 0000000..a546c64
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-return-req3.C
@@ -0,0 +1,6 @@
+// PR c++/100946
+// { dg-do compile { target c++20 } }
+
+template<class T> concept C = __is_same(T, int);
+static_assert(requires { { 0 } -> C; });
+static_assert(requires { { true } -> C; }); // { dg-error "failed" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
index dc46e48..3239df8 100644
--- a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
+++ b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
@@ -520,13 +520,11 @@
# error "__cpp_constexpr_in_decltype != 201711"
#endif
-/* Not supported fully yet:
#ifndef __cpp_consteval
# error "__cpp_consteval"
#elif __cpp_consteval != 201811
# error "__cpp_consteval != 201811"
#endif
-*/
#ifndef __cpp_concepts
# error "__cpp_concepts"
diff --git a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C
new file mode 100644
index 0000000..0de6bf7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated12.C
@@ -0,0 +1,79 @@
+// PR c++/100995
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wtautological-compare" }
+
+namespace std {
+ constexpr inline bool
+ is_constant_evaluated () noexcept
+ {
+ return __builtin_is_constant_evaluated ();
+ }
+}
+
+template <int I = []() constexpr { if (std::is_constant_evaluated()) return 1; return 0; }()>
+struct X { };
+
+template <int I = [](){ if (std::is_constant_evaluated()) return 1; return 0; }()>
+struct Y { };
+
+template <int I = [](){ if constexpr (std::is_constant_evaluated()) return 1; return 0; }()> // { dg-warning "always evaluates to true" }
+struct Z { };
+
+constexpr bool b = true;
+
+#define __glibcxx_assert(cond) \
+ if (__builtin_is_constant_evaluated() && !bool(cond)) \
+__builtin_unreachable()
+#define CHECK __builtin_is_constant_evaluated() // { dg-warning "always evaluates to false" }
+#define CHECK2 __builtin_is_constant_evaluated()
+
+int
+foo ()
+{
+ if (std::is_constant_evaluated ()) // { dg-warning "always evaluates to false" }
+ return 1;
+ __glibcxx_assert(b);
+ if (CHECK && b)
+ return 2;
+ if (CHECK2)
+ return 3;
+ return 0;
+}
+
+constexpr int
+bar ()
+{
+ if (std::is_constant_evaluated ())
+ return 1;
+ if constexpr (std::is_constant_evaluated ()) // { dg-warning "always evaluates to true" }
+ return 2;
+ if constexpr (std::is_constant_evaluated () && b) // { dg-warning "always evaluates to true" }
+ return 3;
+ if constexpr (!std::is_constant_evaluated ()) // { dg-warning "always evaluates to true" }
+ return 4;
+ return 0;
+}
+
+consteval int
+baz ()
+{
+ if (std::is_constant_evaluated ()) // { dg-warning "always evaluates to true" }
+ return 1;
+ return 0;
+}
+
+int
+qux ()
+{
+ if (({ static bool a = std::is_constant_evaluated (); a; }))
+ return 1;
+ if (({ bool a = std::is_constant_evaluated (); a; }))
+ return 2;
+ if (static bool a = std::is_constant_evaluated (); a)
+ return 3;
+ if (bool a = std::is_constant_evaluated (); a)
+ return 4;
+ if constexpr (constexpr bool a = std::is_constant_evaluated (); a)
+ return 5;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C
index 0e96a1a..5e405e7 100644
--- a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C
+++ b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C
@@ -32,7 +32,7 @@ constexpr int
foo3(int i)
{
// I is not a constant expression but we short-circuit it.
- if constexpr (__builtin_is_constant_evaluated () || i)
+ if constexpr (__builtin_is_constant_evaluated () || i) // { dg-warning ".std::is_constant_evaluated. always evaluates to true in .if constexpr." }
return 42;
else
return i;
@@ -42,7 +42,7 @@ constexpr int
foo4(int i)
{
const int j = 0;
- if constexpr (j && __builtin_is_constant_evaluated ())
+ if constexpr (j && __builtin_is_constant_evaluated ()) // { dg-warning ".std::is_constant_evaluated. always evaluates to true in .if constexpr." }
return 42;
else
return i;
diff --git a/gcc/testsuite/g++.dg/goacc/mdc.C b/gcc/testsuite/g++.dg/goacc/mdc.C
index b3abab3..e8ba1cc 100644
--- a/gcc/testsuite/g++.dg/goacc/mdc.C
+++ b/gcc/testsuite/g++.dg/goacc/mdc.C
@@ -45,7 +45,7 @@ t1 ()
#pragma acc enter data attach(rz[3]) /* { dg-error "expected pointer in .attach. clause" } */
#pragma acc exit data detach(rz[3]) /* { dg-error "expected pointer in .detach. clause" } */
-#pragma acc acc enter data attach(rs.e)
+#pragma acc enter data attach(rs.e)
#pragma acc exit data detach(rs.e) attach(rz) /* { dg-error ".attach. is not valid for" } */
#pragma acc data attach(rs.e)
diff --git a/gcc/testsuite/g++.dg/opt/pr100852.C b/gcc/testsuite/g++.dg/opt/pr100852.C
new file mode 100644
index 0000000..9d9a9f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr100852.C
@@ -0,0 +1,25 @@
+// PR debug/100852
+// { dg-do compile }
+// { dg-options "-Og -fif-conversion -fno-tree-ccp -fno-tree-copy-prop -fcompare-debug" }
+
+static inline int
+min (unsigned a, int b)
+{
+ return a < b ? a : b;
+}
+
+struct S { S (char); };
+
+static inline S
+foo (unsigned x)
+{
+ int h;
+ h += min (x * 4, h);
+ return h;
+}
+
+void
+bar ()
+{
+ foo (0);
+}
diff --git a/gcc/testsuite/g++.dg/template/ttp34.C b/gcc/testsuite/g++.dg/template/ttp34.C
new file mode 100644
index 0000000..6709406
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template<class> class Purr;
+
+template<template<class> class, class, class>
+class Meow;
+
+template<template<class> class P>
+class Meow<P, P<int>, int> { }; // 1
+
+template<template<class> class P, class T>
+class Meow<P, P<int>, T>; // 2
+
+Meow<Purr, Purr<int>, int> kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34a.C b/gcc/testsuite/g++.dg/template/ttp34a.C
new file mode 100644
index 0000000..e3303dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34a.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template<class> class Purr;
+
+template<template<class> class, class>
+class Meow;
+
+template<template<class> class P>
+class Meow<P, P<int> > { }; // 1
+
+template<template<class> class P, class T>
+class Meow<P, P<T> >; // 2
+
+Meow<Purr, Purr<int> > kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34b.C b/gcc/testsuite/g++.dg/template/ttp34b.C
new file mode 100644
index 0000000..ed3b3e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34b.C
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template<class> class Purr;
+
+template<class, template<class> class>
+class Meow;
+
+template<template<class> class P>
+class Meow<P<int>, P> { }; // 1
+
+template<template<class> class P, class T>
+class Meow<P<T>, P>; // 2
+
+Meow<Purr<int>, Purr> kitty;
diff --git a/gcc/testsuite/gcc.dg/pr100788.c b/gcc/testsuite/gcc.dg/pr100788.c
new file mode 100644
index 0000000..6f510ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr100788.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "--coverage -Wno-error=coverage-invalid-line-number" } */
+
+void
+foo() // { dg-warning "function starts on a higher line number than it ends" }
+{
+#line 1
+}
+
+int main()
+{
+ foo ();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr101009.c b/gcc/testsuite/gcc.dg/torture/pr101009.c
new file mode 100644
index 0000000..2bbed1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr101009.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fno-tree-sra -fno-tree-pre -ftree-loop-distribution" } */
+
+struct a {
+ unsigned b;
+ unsigned c;
+} e, *f = &e;
+int d = 1;
+int main() {
+ for (; d; d--) {
+ struct a g[] = {{2, 1}, {2, 1}};
+ *f = g[1];
+ }
+ if (e.c != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr56541.c b/gcc/testsuite/gcc.dg/vect/pr56541.c
index e1cee6d..fa86142 100644
--- a/gcc/testsuite/gcc.dg/vect/pr56541.c
+++ b/gcc/testsuite/gcc.dg/vect/pr56541.c
@@ -24,4 +24,4 @@ void foo()
}
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect_floatint_cvt } xfail { ! vect_cond_mixed } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_floatint_cvt } xfail { ! vect_cond_mixed } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr101021-1.c b/gcc/testsuite/gcc.target/i386/pr101021-1.c
new file mode 100644
index 0000000..f4649c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101021-1.c
@@ -0,0 +1,35 @@
+/* PR target/101021 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler-not "vpshufb" } } */
+
+typedef char S;
+typedef S V __attribute__((vector_size(16 * sizeof(S))));
+
+V t1 (V x)
+{
+ return __builtin_shuffle (x, (V) { 8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7 });
+}
+
+/* { dg-final { scan-assembler "vpalignr" } } */
+
+V t2 (V x)
+{
+ return __builtin_shuffle (x, (V) { 0,1,2,3, 4,5,6,7, 4,5,6,7, 12,13,14,15 });
+}
+
+/* { dg-final { scan-assembler "vpshufd" } } */
+
+V t3 (V x)
+{
+ return __builtin_shuffle (x, (V) { 0,1, 2,3, 2,3, 6,7, 8,9,10,11,12,13,14,15 });
+}
+
+/* { dg-final { scan-assembler "vpshuflw" } } */
+
+V t4 (V x)
+{
+ return __builtin_shuffle (x, (V) { 0,1,2,3,4,5,6,7, 8,9, 10,11, 10,11, 14,15 });
+}
+
+/* { dg-final { scan-assembler "vpshufhw" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr101021-2.c b/gcc/testsuite/gcc.target/i386/pr101021-2.c
new file mode 100644
index 0000000..1e046f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101021-2.c
@@ -0,0 +1,21 @@
+/* PR target/101021 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler-not "vpshufb" } } */
+
+typedef char S;
+typedef S V __attribute__((vector_size(8 * sizeof(S))));
+
+V t1 (V x)
+{
+ return __builtin_shuffle (x, (V) { 4,5,6,7, 0,1,2,3 });
+}
+
+/* { dg-final { scan-assembler "vpshufd" } } */
+
+V t2 (V x)
+{
+ return __builtin_shuffle (x, (V) { 0,1, 2,3, 2,3, 6,7 });
+}
+
+/* { dg-final { scan-assembler "vpshuflw" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-builtin-4.c b/gcc/testsuite/gcc.target/powerpc/mma-builtin-4.c
index 3bedf53..a9fb010 100644
--- a/gcc/testsuite/gcc.target/powerpc/mma-builtin-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/mma-builtin-4.c
@@ -21,6 +21,14 @@ foo2 (__vector_pair *dst, vec_t *src)
}
void
+foo3 (__vector_pair *dst, vec_t *src)
+{
+ __vector_pair pair;
+ __builtin_vsx_build_pair (&pair, src[4], src[0]);
+ *dst = pair;
+}
+
+void
bar (vec_t *dst, __vector_pair *src)
{
vec_t res[2];
@@ -54,8 +62,12 @@ bar2 (vec_t *dst, __vector_pair *src)
# error "__has_builtin (__builtin_mma_disassemble_pair) failed"
#endif
-/* { dg-final { scan-assembler-times {\mlxv\M} 4 } } */
+#if !__has_builtin (__builtin_vsx_build_pair)
+# error "__has_builtin (__builtin_vsx_build_pair) failed"
+#endif
+
+/* { dg-final { scan-assembler-times {\mlxv\M} 6 } } */
/* { dg-final { scan-assembler-times {\mlxvp\M} 2 } } */
/* { dg-final { scan-assembler-times {\mstxv\M} 4 } } */
-/* { dg-final { scan-assembler-times {\mstxvp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mstxvp\M} 3 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mma-builtin-5.c b/gcc/testsuite/gcc.target/powerpc/mma-builtin-5.c
index 43b6d3a..00503b7 100644
--- a/gcc/testsuite/gcc.target/powerpc/mma-builtin-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/mma-builtin-5.c
@@ -13,6 +13,14 @@ foo (__vector_quad *dst, vec_t *src)
}
void
+foo2 (__vector_quad *dst, vec_t *src)
+{
+ __vector_quad acc;
+ __builtin_mma_build_acc (&acc, src[12], src[8], src[4], src[0]);
+ *dst = acc;
+}
+
+void
bar (vec_t *dst, __vector_quad *src)
{
vec_t res[4];
@@ -23,9 +31,17 @@ bar (vec_t *dst, __vector_quad *src)
dst[12] = res[3];
}
-/* { dg-final { scan-assembler-times {\mlxv\M} 4 } } */
+#if !__has_builtin (__builtin_mma_assemble_acc)
+# error "__has_builtin (__builtin_mma_assemble_acc) failed"
+#endif
+
+#if !__has_builtin (__builtin_mma_build_acc)
+# error "__has_builtin (__builtin_mma_build_acc) failed"
+#endif
+
+/* { dg-final { scan-assembler-times {\mlxv\M} 8 } } */
/* { dg-final { scan-assembler-times {\mlxvp\M} 2 } } */
/* { dg-final { scan-assembler-times {\mstxv\M} 4 } } */
-/* { dg-final { scan-assembler-times {\mstxvp\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mxxmfacc\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mxxmtacc\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mstxvp\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mxxmfacc\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mxxmtacc\M} 3 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c b/gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c
new file mode 100644
index 0000000..19701c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-fpcvt-3.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2" } */
+
+/* Note that for unsigned cases, the differences from those ones in
+ p9-fpcvt-2.c is that they will be converted to int implicitly first
+ and then to floating point. */
+
+double sc_df (signed char *p, double df) { return *p + df; }
+double uc_df (unsigned char *p, double df) { return *p + df; }
+double ss_df (signed short *p, double df) { return *p + df; }
+double us_df (unsigned short *p, double df) { return *p + df; }
+
+float sc_sf (signed char *p, float sf) { return *p + sf; }
+float uc_sf (unsigned char *p, float sf) { return *p + sf; }
+float ss_sf (signed short *p, float sf) { return *p + sf; }
+float us_sf (unsigned short *p, float sf) { return *p + sf; }
+
+/* { dg-final { scan-assembler {\mlxsibzx\M} } } */
+/* { dg-final { scan-assembler {\mlxsihzx\M} } } */
+/* { dg-final { scan-assembler {\mvextsb2d\M} } } */
+/* { dg-final { scan-assembler {\mvextsh2d\M} } } */
+/* { dg-final { scan-assembler-not {\mm[tf]vsr} } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/vcond-mixed-double.c b/gcc/testsuite/gcc.target/s390/vector/vcond-mixed-double.c
new file mode 100644
index 0000000..015bc8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vcond-mixed-double.c
@@ -0,0 +1,41 @@
+/* Check for vectorization of mixed conditionals. */
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O2 -march=z14 -mzarch -ftree-vectorize -fdump-tree-vect-details" } */
+
+double xd[1024];
+double zd[1024];
+double wd[1024];
+
+long xl[1024];
+long zl[1024];
+long wl[1024];
+
+void foold ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zd[i] = xl[i] ? zd[i] : wd[i];
+}
+
+void foodl ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zl[i] = xd[i] ? zl[i] : wl[i];
+}
+
+void foold2 ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zd[i] = (xd[i] > 0) ? zd[i] : wd[i];
+}
+
+void foold3 ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zd[i] = (xd[i] > 0. & wd[i] < 0.) ? zd[i] : wd[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/vcond-mixed-float.c b/gcc/testsuite/gcc.target/s390/vector/vcond-mixed-float.c
new file mode 100644
index 0000000..ba40ffe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vcond-mixed-float.c
@@ -0,0 +1,41 @@
+/* Check for vectorization of mixed conditionals. */
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O2 -march=z14 -mzarch -ftree-vectorize -fdump-tree-vect-details" } */
+
+float xf[1024];
+float zf[1024];
+float wf[1024];
+
+int xi[1024];
+int zi[1024];
+int wi[1024];
+
+void fooif ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zf[i] = xi[i] ? zf[i] : wf[i];
+}
+
+void foofi ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zi[i] = xf[i] ? zi[i] : wi[i];
+}
+
+void fooif2 ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zf[i] = (xf[i] > 0) ? zf[i] : wf[i];
+}
+
+void fooif3 ()
+{
+ int i;
+ for (i = 0; i < 1024; ++i)
+ zf[i] = (xf[i] > 0.f & wf[i] < 0.f) ? zf[i] : wf[i];
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
diff --git a/gcc/testsuite/gdc.dg/pr100967.d b/gcc/testsuite/gdc.dg/pr100967.d
new file mode 100644
index 0000000..582ad58
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr100967.d
@@ -0,0 +1,11 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100967
+// { dg-do compile }
+
+module object; // { dg-error "class object.TypeInfo missing or corrupt object.d" }
+
+extern(C) int main()
+{
+ int[int] aa;
+ aa[0] = 1; // { dg-error ".object.TypeInfo. could not be found, but is implicitly used" }
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/goacc/attach-descriptor.f90 b/gcc/testsuite/gfortran.dg/goacc/attach-descriptor.f90
index 373bdcb..8c2ee4a 100644
--- a/gcc/testsuite/gfortran.dg/goacc/attach-descriptor.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/attach-descriptor.f90
@@ -12,11 +12,11 @@ program att
!$acc enter data attach(myvar%arr2, myptr)
! { dg-final { scan-tree-dump-times "(?n)#pragma acc enter data map\\(attach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(attach:\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) myptr\\.data \\\[bias: 0\\\]\\);$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(attach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(attach:myptr\\.data \\\[bias: 0\\\]\\)$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_data map\\(attach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(attach:myptr\\.data \\\[bias: 0\\\]\\)$" 1 "gimple" } }
!$acc exit data detach(myvar%arr2, myptr)
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(detach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(detach:\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) myptr\\.data \\\[bias: 0\\\]\\);$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(detach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(detach:myptr\\.data \\\[bias: 0\\\]\\)$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(detach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(detach:myptr\\.data \\\[bias: 0\\\]\\)$" 1 "gimple" } }
! Test valid usage and processing of the finalize clause.
!$acc exit data detach(myvar%arr2, myptr) finalize
@@ -24,6 +24,6 @@ program att
! For array-descriptor detaches, we no longer generate a "release" mapping
! for the pointed-to data for gimplify.c to turn into "delete". Make sure
! the mapping still isn't there.
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(force_detach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(force_detach:myptr\\.data \\\[bias: 0\\\]\\) finalize$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(force_detach:myvar\\.arr2 \\\[bias: 0\\\]\\) map\\(to:myptr \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(force_detach:myptr\\.data \\\[bias: 0\\\]\\) finalize$" 1 "gimple" } }
end program att
diff --git a/gcc/testsuite/gfortran.dg/goacc/finalize-1.f b/gcc/testsuite/gfortran.dg/goacc/finalize-1.f
index a778858..b706b38 100644
--- a/gcc/testsuite/gfortran.dg/goacc/finalize-1.f
+++ b/gcc/testsuite/gfortran.dg/goacc/finalize-1.f
@@ -13,25 +13,25 @@
!$ACC EXIT DATA DELETE (del_r)
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(release:del_r\\);$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(release:del_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(release:del_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } }
!$ACC EXIT DATA FINALIZE DELETE (del_f)
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(release:del_f\\) finalize;$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(delete:del_f \\\[len: \[0-9\]+\\\]\\) finalize$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(delete:del_f \\\[len: \[0-9\]+\\\]\\) finalize$" 1 "gimple" } }
!$ACC EXIT DATA FINALIZE DELETE (del_f_p(2:5))
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(release:\\*\\(c_char \\*\\) parm\\.0\\.data \\\[len: \[^\\\]\]+\\\]\\) map\\(to:del_f_p \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(alloc:\\(integer\\(kind=1\\)\\\[0:\\\] \\* restrict\\) del_f_p\\.data \\\[pointer assign, bias: \\(.*int.*\\) parm\\.0\\.data - \\(.*int.*\\) del_f_p\\.data\\\]\\) finalize;$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(delete:MEM\\\[\\(c_char \\*\\)\[^\\\]\]+\\\] \\\[len: \[^\\\]\]+\\\]\\) map\\(to:del_f_p \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(alloc:del_f_p\\.data \\\[pointer assign, bias: \[^\\\]\]+\\\]\\) finalize$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(delete:MEM\\\[\\(c_char \\*\\)\[^\\\]\]+\\\] \\\[len: \[^\\\]\]+\\\]\\) map\\(to:del_f_p \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(alloc:del_f_p\\.data \\\[pointer assign, bias: \[^\\\]\]+\\\]\\) finalize$" 1 "gimple" } }
!$ACC EXIT DATA COPYOUT (cpo_r)
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(from:cpo_r\\);$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(from:cpo_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(from:cpo_r \\\[len: \[0-9\]+\\\]\\)$" 1 "gimple" } }
!$ACC EXIT DATA COPYOUT (cpo_f) FINALIZE
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(from:cpo_f\\) finalize;$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(force_from:cpo_f \\\[len: \[0-9\]+\\\]\\) finalize$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(force_from:cpo_f \\\[len: \[0-9\]+\\\]\\) finalize$" 1 "gimple" } }
!$ACC EXIT DATA COPYOUT (cpo_f_p(4:10)) FINALIZE
! { dg-final { scan-tree-dump-times "(?n)#pragma acc exit data map\\(from:\\*\\(c_char \\*\\) parm\\.1\\.data \\\[len: \[^\\\]\]+\\\]\\) map\\(to:cpo_f_p \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(alloc:\\(integer\\(kind=1\\)\\\[0:\\\] \\* restrict\\) cpo_f_p\\.data \\\[pointer assign, bias: \\(.*int.*\\) parm\\.1\\.data - \\(.*int.*\\) cpo_f_p\\.data\\\]\\) finalize;$" 1 "original" } }
-! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_enter_exit_data map\\(force_from:MEM\\\[\\(c_char \\*\\)\[^\\\]\]+\\\] \\\[len: \[^\\\]\]+\\\]\\) map\\(to:cpo_f_p \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(alloc:cpo_f_p\\.data \\\[pointer assign, bias: \[^\\\]\]+\\\]\\) finalize$" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_exit_data map\\(force_from:MEM\\\[\\(c_char \\*\\)\[^\\\]\]+\\\] \\\[len: \[^\\\]\]+\\\]\\) map\\(to:cpo_f_p \\\[pointer set, len: \[0-9\]+\\\]\\) map\\(alloc:cpo_f_p\\.data \\\[pointer assign, bias: \[^\\\]\]+\\\]\\) finalize$" 1 "gimple" } }
END SUBROUTINE f
diff --git a/gcc/testsuite/gfortran.dg/goacc/mapping-tests-3.f90 b/gcc/testsuite/gfortran.dg/goacc/mapping-tests-3.f90
index 890ca78..662104f 100644
--- a/gcc/testsuite/gfortran.dg/goacc/mapping-tests-3.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/mapping-tests-3.f90
@@ -11,5 +11,5 @@ subroutine foo
type(two) x
!$acc enter data copyin(x%A)
-! { dg-final { scan-tree-dump-times "omp target oacc_enter_exit_data map\\(struct:x \\\[len: 1\\\]\\) map\\(to:x.a \\\[len: \[0-9\]+\\\]\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_enter_data map\\(struct:x \\\[len: 1\\\]\\) map\\(to:x.a \\\[len: \[0-9\]+\\\]\\)" 1 "gimple" } }
end
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 6a6ebe9..55e7550 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1744,12 +1744,19 @@ process_options (void)
/* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
have not been set. */
- if (!global_options_set.x_warnings_are_errors
- && warn_coverage_mismatch
- && (global_dc->classify_diagnostic[OPT_Wcoverage_mismatch] ==
- DK_UNSPECIFIED))
- diagnostic_classify_diagnostic (global_dc, OPT_Wcoverage_mismatch,
- DK_ERROR, UNKNOWN_LOCATION);
+ if (!global_options_set.x_warnings_are_errors)
+ {
+ if (warn_coverage_mismatch
+ && (global_dc->classify_diagnostic[OPT_Wcoverage_mismatch] ==
+ DK_UNSPECIFIED))
+ diagnostic_classify_diagnostic (global_dc, OPT_Wcoverage_mismatch,
+ DK_ERROR, UNKNOWN_LOCATION);
+ if (warn_coverage_invalid_linenum
+ && (global_dc->classify_diagnostic[OPT_Wcoverage_invalid_line_number] ==
+ DK_UNSPECIFIED))
+ diagnostic_classify_diagnostic (global_dc, OPT_Wcoverage_invalid_line_number,
+ DK_ERROR, UNKNOWN_LOCATION);
+ }
/* Save the current optimization options. */
optimization_default_node
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index b1f6468..b37c234 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -5121,6 +5121,8 @@ build_classic_dist_vector_1 (struct data_dependence_relation *ddr,
non_affine_dependence_relation (ddr);
return false;
}
+ else
+ *init_b = true;
}
return true;
@@ -5616,9 +5618,13 @@ compute_affine_dependence (struct data_dependence_relation *ddr,
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "(compute_affine_dependence\n");
- fprintf (dump_file, " stmt_a: ");
+ fprintf (dump_file, " ref_a: ");
+ print_generic_expr (dump_file, DR_REF (dra));
+ fprintf (dump_file, ", stmt_a: ");
print_gimple_stmt (dump_file, DR_STMT (dra), 0, TDF_SLIM);
- fprintf (dump_file, " stmt_b: ");
+ fprintf (dump_file, " ref_b: ");
+ print_generic_expr (dump_file, DR_REF (drb));
+ fprintf (dump_file, ", stmt_b: ");
print_gimple_stmt (dump_file, DR_STMT (drb), 0, TDF_SLIM);
}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 1915d74..6237a61 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1806,6 +1806,11 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
stmt_vec_info def_stmt_info;
bool res = vect_is_simple_use (op, vinfo, &dt, &def_stmt_info);
gcc_assert (res);
+ if (dt == vect_internal_def)
+ {
+ def_stmt_info = vect_stmt_to_vectorize (def_stmt_info);
+ op = gimple_get_lhs (def_stmt_info->stmt);
+ }
gimple *use_stmt;
use_operand_p use_p;
if (dt == vect_internal_def
@@ -1860,7 +1865,7 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
/* Now we have a set of chains with the same length. */
/* 1. pre-sort according to def_type and operation. */
for (unsigned lane = 0; lane < group_size; ++lane)
- chains[lane].sort (dt_sort_cmp, vinfo);
+ chains[lane].stablesort (dt_sort_cmp, vinfo);
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location,
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 821f224..9047e27 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -36,9 +36,9 @@ along with GCC; see the file COPYING3. If not see
// value_query default methods.
tree
-value_query::value_on_edge (edge, tree name)
+value_query::value_on_edge (edge, tree expr)
{
- return value_of_expr (name);
+ return value_of_expr (expr);
}
tree
@@ -57,9 +57,9 @@ value_query::value_of_stmt (gimple *stmt, tree name)
// range_query default methods.
bool
-range_query::range_on_edge (irange &r, edge, tree name)
+range_query::range_on_edge (irange &r, edge, tree expr)
{
- return range_of_expr (r, name);
+ return range_of_expr (r, expr);
}
bool
@@ -76,20 +76,20 @@ range_query::range_of_stmt (irange &r, gimple *stmt, tree name)
}
tree
-range_query::value_of_expr (tree name, gimple *stmt)
+range_query::value_of_expr (tree expr, gimple *stmt)
{
tree t;
int_range_max r;
- if (!irange::supports_type_p (TREE_TYPE (name)))
+ if (!irange::supports_type_p (TREE_TYPE (expr)))
return NULL_TREE;
- if (range_of_expr (r, name, stmt))
+ if (range_of_expr (r, expr, stmt))
{
// A constant used in an unreachable block oftens returns as UNDEFINED.
// If the result is undefined, check the global value for a constant.
if (r.undefined_p ())
- range_of_expr (r, name);
+ range_of_expr (r, expr);
if (r.singleton_p (&t))
return t;
}
@@ -97,19 +97,19 @@ range_query::value_of_expr (tree name, gimple *stmt)
}
tree
-range_query::value_on_edge (edge e, tree name)
+range_query::value_on_edge (edge e, tree expr)
{
tree t;
int_range_max r;
- if (!irange::supports_type_p (TREE_TYPE (name)))
+ if (!irange::supports_type_p (TREE_TYPE (expr)))
return NULL_TREE;
- if (range_on_edge (r, e, name))
+ if (range_on_edge (r, e, expr))
{
// A constant used in an unreachable block oftens returns as UNDEFINED.
// If the result is undefined, check the global value for a constant.
if (r.undefined_p ())
- range_of_expr (r, name);
+ range_of_expr (r, expr);
if (r.singleton_p (&t))
return t;
}
diff --git a/gcc/value-query.h b/gcc/value-query.h
index 77e49e9..54af031 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -39,12 +39,12 @@ class value_query
{
public:
value_query () { }
- // Return the singleton expression for NAME at a gimple statement,
+ // Return the singleton expression for EXPR at a gimple statement,
// or NULL if none found.
- virtual tree value_of_expr (tree name, gimple * = NULL) = 0;
- // Return the singleton expression for NAME at an edge, or NULL if
+ virtual tree value_of_expr (tree expr, gimple * = NULL) = 0;
+ // Return the singleton expression for EXPR at an edge, or NULL if
// none found.
- virtual tree value_on_edge (edge, tree name);
+ virtual tree value_on_edge (edge, tree expr);
// Return the singleton expression for the LHS of a gimple
// statement, assuming an (optional) initial value of NAME. Returns
// NULL if none found.
@@ -77,8 +77,8 @@ public:
range_query ();
virtual ~range_query ();
- virtual tree value_of_expr (tree name, gimple * = NULL) OVERRIDE;
- virtual tree value_on_edge (edge, tree name) OVERRIDE;
+ virtual tree value_of_expr (tree expr, gimple * = NULL) OVERRIDE;
+ virtual tree value_on_edge (edge, tree expr) OVERRIDE;
virtual tree value_of_stmt (gimple *, tree name = NULL) OVERRIDE;
// These are the range equivalents of the value_* methods. Instead
@@ -86,9 +86,9 @@ public:
// R. TRUE is returned on success or FALSE if no range was found.
//
// Note that range_of_expr must always return TRUE unless ranges are
- // unsupported for NAME's type (supports_type_p is false).
- virtual bool range_of_expr (irange &r, tree name, gimple * = NULL) = 0;
- virtual bool range_on_edge (irange &r, edge, tree name);
+ // unsupported for EXPR's type (supports_type_p is false).
+ virtual bool range_of_expr (irange &r, tree expr, gimple * = NULL) = 0;
+ virtual bool range_on_edge (irange &r, edge, tree expr);
virtual bool range_of_stmt (irange &r, gimple *, tree name = NULL);
// DEPRECATED: This method is used from vr-values. The plan is to
diff --git a/gcc/vec.h b/gcc/vec.h
index 24df2db..193377c 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -612,6 +612,7 @@ public:
void block_remove (unsigned, unsigned);
void qsort (int (*) (const void *, const void *));
void sort (int (*) (const void *, const void *, void *), void *);
+ void stablesort (int (*) (const void *, const void *, void *), void *);
T *bsearch (const void *key, int (*compar)(const void *, const void *));
T *bsearch (const void *key,
int (*compar)(const void *, const void *, void *), void *);
@@ -1160,6 +1161,17 @@ vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *),
gcc_sort_r (address (), length (), sizeof (T), cmp, data);
}
+/* Sort the contents of this vector with gcc_stablesort_r. CMP is the
+ comparison function to pass to qsort. */
+
+template<typename T, typename A>
+inline void
+vec<T, A, vl_embed>::stablesort (int (*cmp) (const void *, const void *,
+ void *), void *data)
+{
+ if (length () > 1)
+ gcc_stablesort_r (address (), length (), sizeof (T), cmp, data);
+}
/* Search the contents of the sorted vector with a binary search.
CMP is the comparison function to pass to bsearch. */
@@ -1488,6 +1500,7 @@ public:
void block_remove (unsigned, unsigned);
void qsort (int (*) (const void *, const void *));
void sort (int (*) (const void *, const void *, void *), void *);
+ void stablesort (int (*) (const void *, const void *, void *), void *);
T *bsearch (const void *key, int (*compar)(const void *, const void *));
T *bsearch (const void *key,
int (*compar)(const void *, const void *, void *), void *);
@@ -2053,6 +2066,17 @@ vec<T, va_heap, vl_ptr>::sort (int (*cmp) (const void *, const void *,
m_vec->sort (cmp, data);
}
+/* Sort the contents of this vector with gcc_stablesort_r. CMP is the
+ comparison function to pass to qsort. */
+
+template<typename T>
+inline void
+vec<T, va_heap, vl_ptr>::stablesort (int (*cmp) (const void *, const void *,
+ void *), void *data)
+{
+ if (m_vec)
+ m_vec->stablesort (cmp, data);
+}
/* Search the contents of the sorted vector with a binary search.
CMP is the comparison function to pass to bsearch. */
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 53b66f8..62852e6 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,8 @@
+2021-06-10 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/quad-float128.h: Guard all uses of [U]TItype_ppc by
+ _ARCH_PPC64 .
+
2021-06-09 Carl Love <cel@us.ibm.com>
* config.host: Add if test and set for
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index c4d775b..c7f2b77 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -88,12 +88,16 @@ extern USItype_ppc __fixunskfsi_sw (TFtype);
extern UDItype_ppc __fixunskfdi_sw (TFtype);
extern TFtype __floatsikf_sw (SItype_ppc);
extern TFtype __floatdikf_sw (DItype_ppc);
+#ifdef _ARCH_PPC64
extern TFtype __floattikf_sw (TItype_ppc);
+#endif
extern TFtype __floatunsikf_sw (USItype_ppc);
extern TFtype __floatundikf_sw (UDItype_ppc);
+#ifdef _ARCH_PPC64
extern TFtype __floatuntikf_sw (UTItype_ppc);
extern TItype_ppc __fixkfti_sw (TFtype);
extern UTItype_ppc __fixunskfti_sw (TFtype);
+#endif
extern IBM128_TYPE __extendkftf2_sw (TFtype);
extern TFtype __trunctfkf2_sw (IBM128_TYPE);
extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype);
@@ -130,12 +134,16 @@ extern USItype_ppc __fixunskfsi_hw (TFtype);
extern UDItype_ppc __fixunskfdi_hw (TFtype);
extern TFtype __floatsikf_hw (SItype_ppc);
extern TFtype __floatdikf_hw (DItype_ppc);
+#ifdef _ARCH_PPC64
extern TFtype __floattikf_hw (TItype_ppc);
+#endif
extern TFtype __floatunsikf_hw (USItype_ppc);
extern TFtype __floatundikf_hw (UDItype_ppc);
+#ifdef _ARCH_PPC64
extern TFtype __floatuntikf_hw (UTItype_ppc);
extern TItype_ppc __fixkfti_hw (TFtype);
extern UTItype_ppc __fixunskfti_hw (TFtype);
+#endif
extern IBM128_TYPE __extendkftf2_hw (TFtype);
extern TFtype __trunctfkf2_hw (IBM128_TYPE);
extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype);
@@ -166,12 +174,16 @@ extern USItype_ppc __fixunskfsi (TFtype);
extern UDItype_ppc __fixunskfdi (TFtype);
extern TFtype __floatsikf (SItype_ppc);
extern TFtype __floatdikf (DItype_ppc);
+#ifdef _ARCH_PPC64
extern TFtype __floattikf (TItype_ppc);
+#endif
extern TFtype __floatunsikf (USItype_ppc);
extern TFtype __floatundikf (UDItype_ppc);
+#ifdef _ARCH_PPC64
extern TFtype __floatuntikf (UTItype_ppc);
extern TItype_ppc __fixkfti (TFtype);
extern UTItype_ppc __fixunskfti (TFtype);
+#endif
extern IBM128_TYPE __extendkftf2 (TFtype);
extern TFtype __trunctfkf2 (IBM128_TYPE);
diff --git a/libgo/MERGE b/libgo/MERGE
index 81cd062..ac84271 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-9baddd3f21230c55f0ad2a10f5f20579dcf0a0bb
+7677616a263e8ded606cc8297cb67ddc667a876e
The first line of this file holds the git revision number of the
last merge done from the master library sources.
diff --git a/libgo/VERSION b/libgo/VERSION
index e592dfd..e336ec2 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.16.3
+go1.16.5
diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go
index c288ad9..ddef2b7 100644
--- a/libgo/go/archive/zip/reader.go
+++ b/libgo/go/archive/zip/reader.go
@@ -99,7 +99,15 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
return err
}
z.r = r
- z.File = make([]*File, 0, end.directoryRecords)
+ // Since the number of directory records is not validated, it is not
+ // safe to preallocate z.File without first checking that the specified
+ // number of files is reasonable, since a malformed archive may
+ // indicate it contains up to 1 << 128 - 1 files. Since each file has a
+ // header which will be _at least_ 30 bytes we can safely preallocate
+ // if (data size / 30) >= end.directoryRecords.
+ if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+ z.File = make([]*File, 0, end.directoryRecords)
+ }
z.Comment = end.comment
rs := io.NewSectionReader(r, 0, size)
if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != nil {
@@ -628,10 +636,11 @@ func (b *readBuf) sub(n int) readBuf {
}
// A fileListEntry is a File and its ename.
-// If file == nil, the fileListEntry describes a directory, without metadata.
+// If file == nil, the fileListEntry describes a directory without metadata.
type fileListEntry struct {
- name string
- file *File // nil for directories
+ name string
+ file *File
+ isDir bool
}
type fileInfoDirEntry interface {
@@ -640,20 +649,26 @@ type fileInfoDirEntry interface {
}
func (e *fileListEntry) stat() fileInfoDirEntry {
- if e.file != nil {
+ if !e.isDir {
return headerFileInfo{&e.file.FileHeader}
}
return e
}
// Only used for directories.
-func (f *fileListEntry) Name() string { _, elem, _ := split(f.name); return elem }
-func (f *fileListEntry) Size() int64 { return 0 }
-func (f *fileListEntry) ModTime() time.Time { return time.Time{} }
-func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
-func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
-func (f *fileListEntry) IsDir() bool { return true }
-func (f *fileListEntry) Sys() interface{} { return nil }
+func (f *fileListEntry) Name() string { _, elem, _ := split(f.name); return elem }
+func (f *fileListEntry) Size() int64 { return 0 }
+func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
+func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
+func (f *fileListEntry) IsDir() bool { return true }
+func (f *fileListEntry) Sys() interface{} { return nil }
+
+func (f *fileListEntry) ModTime() time.Time {
+ if f.file == nil {
+ return time.Time{}
+ }
+ return f.file.FileHeader.Modified.UTC()
+}
func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil }
@@ -673,15 +688,32 @@ func toValidName(name string) string {
func (r *Reader) initFileList() {
r.fileListOnce.Do(func() {
dirs := make(map[string]bool)
+ knownDirs := make(map[string]bool)
for _, file := range r.File {
+ isDir := len(file.Name) > 0 && file.Name[len(file.Name)-1] == '/'
name := toValidName(file.Name)
for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
dirs[dir] = true
}
- r.fileList = append(r.fileList, fileListEntry{name, file})
+ entry := fileListEntry{
+ name: name,
+ file: file,
+ isDir: isDir,
+ }
+ r.fileList = append(r.fileList, entry)
+ if isDir {
+ knownDirs[name] = true
+ }
}
for dir := range dirs {
- r.fileList = append(r.fileList, fileListEntry{dir + "/", nil})
+ if !knownDirs[dir] {
+ entry := fileListEntry{
+ name: dir,
+ file: nil,
+ isDir: true,
+ }
+ r.fileList = append(r.fileList, entry)
+ }
}
sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) })
@@ -705,7 +737,7 @@ func (r *Reader) Open(name string) (fs.File, error) {
if e == nil || !fs.ValidPath(name) {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
- if e.file == nil || strings.HasSuffix(e.file.Name, "/") {
+ if e.isDir {
return &openDir{e, r.openReadDir(name), 0}, nil
}
rc, err := e.file.Open()
@@ -730,7 +762,7 @@ func split(name string) (dir, elem string, isDir bool) {
return name[:i], name[i+1:], isDir
}
-var dotFile = &fileListEntry{name: "./"}
+var dotFile = &fileListEntry{name: "./", isDir: true}
func (r *Reader) openLookup(name string) *fileListEntry {
if name == "." {
diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go
index 5faf1f4..471be27 100644
--- a/libgo/go/archive/zip/reader_test.go
+++ b/libgo/go/archive/zip/reader_test.go
@@ -1073,12 +1073,62 @@ func TestIssue12449(t *testing.T) {
}
func TestFS(t *testing.T) {
- z, err := OpenReader("testdata/unix.zip")
+ for _, test := range []struct {
+ file string
+ want []string
+ }{
+ {
+ "testdata/unix.zip",
+ []string{"hello", "dir/bar", "readonly"},
+ },
+ {
+ "testdata/subdir.zip",
+ []string{"a/b/c"},
+ },
+ } {
+ t.Run(test.file, func(t *testing.T) {
+ t.Parallel()
+ z, err := OpenReader(test.file)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer z.Close()
+ if err := fstest.TestFS(z, test.want...); err != nil {
+ t.Error(err)
+ }
+ })
+ }
+}
+
+func TestFSModTime(t *testing.T) {
+ t.Parallel()
+ z, err := OpenReader("testdata/subdir.zip")
if err != nil {
t.Fatal(err)
}
- if err := fstest.TestFS(z, "hello", "dir/bar", "dir/empty", "readonly"); err != nil {
- t.Fatal(err)
+ defer z.Close()
+
+ for _, test := range []struct {
+ name string
+ want time.Time
+ }{
+ {
+ "a",
+ time.Date(2021, 4, 19, 12, 29, 56, 0, timeZone(-7*time.Hour)).UTC(),
+ },
+ {
+ "a/b/c",
+ time.Date(2021, 4, 19, 12, 29, 59, 0, timeZone(-7*time.Hour)).UTC(),
+ },
+ } {
+ fi, err := fs.Stat(z, test.name)
+ if err != nil {
+ t.Errorf("%s: %v", test.name, err)
+ continue
+ }
+ if got := fi.ModTime(); !got.Equal(test.want) {
+ t.Errorf("%s: got modtime %v, want %v", test.name, got, test.want)
+ }
}
}
@@ -1116,3 +1166,62 @@ func TestCVE202127919(t *testing.T) {
t.Errorf("Error reading file: %v", err)
}
}
+
+func TestCVE202133196(t *testing.T) {
+ // Archive that indicates it has 1 << 128 -1 files,
+ // this would previously cause a panic due to attempting
+ // to allocate a slice with 1 << 128 -1 elements.
+ data := []byte{
+ 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x03, 0x62, 0x61, 0x65, 0x03, 0x04, 0x00, 0x00,
+ 0xff, 0xff, 0x50, 0x4b, 0x07, 0x08, 0xbe, 0x20,
+ 0x5c, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
+ 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xbe, 0x20, 0x5c, 0x6c, 0x09, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x03, 0x50, 0x4b, 0x06, 0x06, 0x2c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50,
+ 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x00, 0x00,
+ }
+ _, err := NewReader(bytes.NewReader(data), int64(len(data)))
+ if err != ErrFormat {
+ t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
+ }
+
+ // Also check that an archive containing a handful of empty
+ // files doesn't cause an issue
+ b := bytes.NewBuffer(nil)
+ w := NewWriter(b)
+ for i := 0; i < 5; i++ {
+ _, err := w.Create("")
+ if err != nil {
+ t.Fatalf("Writer.Create failed: %s", err)
+ }
+ }
+ if err := w.Close(); err != nil {
+ t.Fatalf("Writer.Close failed: %s", err)
+ }
+ r, err := NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
+ if err != nil {
+ t.Fatalf("NewReader failed: %s", err)
+ }
+ if len(r.File) != 5 {
+ t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
+ }
+}
diff --git a/libgo/go/archive/zip/testdata/subdir.zip b/libgo/go/archive/zip/testdata/subdir.zip
new file mode 100644
index 0000000..324d06b
--- /dev/null
+++ b/libgo/go/archive/zip/testdata/subdir.zip
Binary files differ
diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go
index e7d3d86..a602bb9 100644
--- a/libgo/go/cmd/go/internal/modcmd/download.go
+++ b/libgo/go/cmd/go/internal/modcmd/download.go
@@ -86,9 +86,11 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
if !modload.HasModRoot() && len(args) == 0 {
base.Fatalf("go mod download: no modules specified (see 'go help mod download')")
}
- if len(args) == 0 {
+ haveExplicitArgs := len(args) > 0
+ if !haveExplicitArgs {
args = []string{"all"}
- } else if modload.HasModRoot() {
+ }
+ if modload.HasModRoot() {
modload.LoadModFile(ctx) // to fill Target
targetAtUpgrade := modload.Target.Path + "@upgrade"
targetAtPatch := modload.Target.Path + "@patch"
@@ -137,7 +139,20 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
listRetractions := false
type token struct{}
sem := make(chan token, runtime.GOMAXPROCS(0))
- for _, info := range modload.ListModules(ctx, args, listU, listVersions, listRetractions) {
+ infos := modload.ListModules(ctx, args, listU, listVersions, listRetractions)
+ if !haveExplicitArgs {
+ // 'go mod download' is sometimes run without arguments to pre-populate
+ // the module cache. It may fetch modules that aren't needed to build
+ // packages in the main mdoule. This is usually not intended, so don't save
+ // sums for downloaded modules (golang.org/issue/45332).
+ // TODO(golang.org/issue/45551): For now, save sums needed to load the
+ // build list (same as 1.15 behavior). In the future, report an error if
+ // go.mod or go.sum need to be updated after loading the build list.
+ modload.WriteGoMod()
+ modload.DisallowWriteGoMod()
+ }
+
+ for _, info := range infos {
if info.Replace != nil {
info = info.Replace
}
@@ -187,6 +202,13 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
base.ExitIfErrors()
}
- // Update go.mod and especially go.sum if needed.
- modload.WriteGoMod()
+ // If there were explicit arguments, update go.mod and especially go.sum.
+ // 'go mod download mod@version' is a useful way to add a sum without using
+ // 'go get mod@version', which may have other side effects. We print this in
+ // some error message hints.
+ //
+ // Don't save sums for 'go mod download' without arguments; see comment above.
+ if haveExplicitArgs {
+ modload.WriteGoMod()
+ }
}
diff --git a/libgo/go/cmd/go/internal/modcmd/tidy.go b/libgo/go/cmd/go/internal/modcmd/tidy.go
index 8bc9ed5..67f90b1 100644
--- a/libgo/go/cmd/go/internal/modcmd/tidy.go
+++ b/libgo/go/cmd/go/internal/modcmd/tidy.go
@@ -61,6 +61,8 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
modload.ForceUseModules = true
modload.RootMode = modload.NeedRoot
+ modload.CheckTidyVersion(ctx, tidyE)
+
modload.LoadPackages(ctx, modload.PackageOpts{
Tags: imports.AnyTags(),
ResolveMissingImports: true,
diff --git a/libgo/go/cmd/go/internal/modload/buildlist.go b/libgo/go/cmd/go/internal/modload/buildlist.go
index 45f220a..0ed9853 100644
--- a/libgo/go/cmd/go/internal/modload/buildlist.go
+++ b/libgo/go/cmd/go/internal/modload/buildlist.go
@@ -11,10 +11,13 @@ import (
"cmd/go/internal/mvs"
"context"
"fmt"
+ "go/build"
"os"
"strings"
+ "golang.org/x/mod/modfile"
"golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
)
// buildList is the list of modules to use for building packages.
@@ -226,6 +229,33 @@ func ReloadBuildList() []module.Version {
return capVersionSlice(buildList)
}
+// CheckTidyVersion reports an error to stderr if the Go version indicated by
+// the go.mod file is not supported by this version of the 'go' command.
+//
+// If allowError is false, such an error terminates the program.
+func CheckTidyVersion(ctx context.Context, allowError bool) {
+ LoadModFile(ctx)
+ if index.goVersionV == "" {
+ return
+ }
+
+ tags := build.Default.ReleaseTags
+ maxGo := tags[len(tags)-1]
+ if !strings.HasPrefix(maxGo, "go") || !modfile.GoVersionRE.MatchString(maxGo[2:]) {
+ base.Fatalf("go: unrecognized go version %q", maxGo)
+ }
+ max := maxGo[2:]
+
+ if semver.Compare(index.goVersionV, "v"+max) > 0 {
+ have := index.goVersionV[1:]
+ if allowError {
+ fmt.Fprintf(os.Stderr, "go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max)
+ } else {
+ base.Fatalf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max)
+ }
+ }
+}
+
// TidyBuildList trims the build list to the minimal requirements needed to
// retain the same versions of all packages from the preceding call to
// LoadPackages.
diff --git a/libgo/go/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt b/libgo/go/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
index 00b71bf..7982ccc 100644
--- a/libgo/go/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
+++ b/libgo/go/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
@@ -5,7 +5,7 @@ module "rsc.io/sampler"
require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c
-- .info --
-{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"}EOF
+{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"}
-- hello.go --
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/libgo/go/cmd/go/testdata/script/mod_download.txt b/libgo/go/cmd/go/testdata/script/mod_download.txt
index 8a9faff..c2b72b2 100644
--- a/libgo/go/cmd/go/testdata/script/mod_download.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_download.txt
@@ -107,13 +107,28 @@ stderr '^go mod download: skipping argument m that resolves to the main module\n
! go mod download m@latest
stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$'
-# download updates go.mod and populates go.sum
+# download without arguments updates go.mod and go.sum after loading the
+# build list, but does not save sums for downloaded zips.
cd update
+cp go.mod.orig go.mod
! exists go.sum
go mod download
+cmp go.mod.update go.mod
+cmp go.sum.update go.sum
+cp go.mod.orig go.mod
+rm go.sum
+
+# download with arguments (even "all") does update go.mod and go.sum.
+go mod download rsc.io/sampler
+cmp go.mod.update go.mod
grep '^rsc.io/sampler v1.3.0 ' go.sum
-go list -m rsc.io/sampler
-stdout '^rsc.io/sampler v1.3.0$'
+cp go.mod.orig go.mod
+rm go.sum
+
+go mod download all
+cmp go.mod.update go.mod
+grep '^rsc.io/sampler v1.3.0 ' go.sum
+cd ..
# allow go mod download without go.mod
env GO111MODULE=auto
@@ -131,7 +146,7 @@ stderr 'get '$GOPROXY
-- go.mod --
module m
--- update/go.mod --
+-- update/go.mod.orig --
module m
go 1.16
@@ -140,3 +155,16 @@ require (
rsc.io/quote v1.5.2
rsc.io/sampler v1.2.1 // older version than in build list
)
+-- update/go.mod.update --
+module m
+
+go 1.16
+
+require (
+ rsc.io/quote v1.5.2
+ rsc.io/sampler v1.3.0 // older version than in build list
+)
+-- update/go.sum.update --
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt b/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt
index 3b38d8b..c536693 100644
--- a/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt
@@ -1,6 +1,3 @@
-# Populate go.sum
-go mod download
-
# go list should succeed to load a package ending with ".go" if the path does
# not correspond to an existing local file. Listing a pattern ending with
# ".go/" should try to list a package regardless of whether a file exists at the
@@ -31,3 +28,10 @@ module m
go 1.13
require example.com/dotgo.go v1.0.0
+-- go.sum --
+example.com/dotgo.go v1.0.0 h1:XKJfs0V8x2PvY2tX8bJBCEbCDLnt15ma2onwhVpew/I=
+example.com/dotgo.go v1.0.0/go.mod h1:Qi6z/X3AC5vHiuMt6HF2ICx3KhIBGrMdrA7YoPDKqR0=
+-- use.go --
+package use
+
+import _ "example.com/dotgo.go"
diff --git a/libgo/go/cmd/go/testdata/script/mod_query.txt b/libgo/go/cmd/go/testdata/script/mod_query.txt
index e101857..a75f86e 100644
--- a/libgo/go/cmd/go/testdata/script/mod_query.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_query.txt
@@ -1,9 +1,7 @@
env GO111MODULE=on
-# Populate go.sum.
# TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands
# below depend on the build list.
-go mod download
go list -m -versions rsc.io/quote
stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$'
@@ -36,6 +34,9 @@ stdout 'no matching versions for query ">v1.5.3"'
module x
require rsc.io/quote v1.0.0
+-- go.sum --
+rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw=
+rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA=
-- use.go --
package use
diff --git a/libgo/go/cmd/go/testdata/script/mod_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_readonly.txt
index 176be72..d05ad2a 100644
--- a/libgo/go/cmd/go/testdata/script/mod_readonly.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_readonly.txt
@@ -89,7 +89,7 @@ stderr '^no required module provides package rsc.io/quote; to add it:\n\tgo get
-- go.mod --
module m
-go 1.20
+go 1.16
-- x.go --
package x
@@ -104,7 +104,7 @@ require (
-- go.mod.redundant --
module m
-go 1.20
+go 1.16
require (
rsc.io/quote v1.5.2
@@ -114,7 +114,7 @@ require (
-- go.mod.indirect --
module m
-go 1.20
+go 1.16
require (
rsc.io/quote v1.5.2 // indirect
@@ -124,7 +124,7 @@ require (
-- go.mod.untidy --
module m
-go 1.20
+go 1.16
require (
rsc.io/sampler v1.3.0 // indirect
diff --git a/libgo/go/go.mod b/libgo/go/go.mod
index 4ae14ee..798677b 100644
--- a/libgo/go/go.mod
+++ b/libgo/go/go.mod
@@ -4,7 +4,7 @@ go 1.16
require (
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
- golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
+ golang.org/x/net v0.0.0-20210428183300-3f4a416c7d3b
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
golang.org/x/text v0.3.4 // indirect
)
diff --git a/libgo/go/golang.org/x/net/http/httpguts/httplex.go b/libgo/go/golang.org/x/net/http/httpguts/httplex.go
index e7de24e..c79aa73 100644
--- a/libgo/go/golang.org/x/net/http/httpguts/httplex.go
+++ b/libgo/go/golang.org/x/net/http/httpguts/httplex.go
@@ -137,11 +137,13 @@ func trimOWS(x string) string {
// contains token amongst its comma-separated tokens, ASCII
// case-insensitively.
func headerValueContainsToken(v string, token string) bool {
- v = trimOWS(v)
- if comma := strings.IndexByte(v, ','); comma != -1 {
- return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
+ for comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {
+ if tokenEqual(trimOWS(v[:comma]), token) {
+ return true
+ }
+ v = v[comma+1:]
}
- return tokenEqual(v, token)
+ return tokenEqual(trimOWS(v), token)
}
// lowerASCII returns the ASCII lowercase version of b.
diff --git a/libgo/go/math/big/ratconv.go b/libgo/go/math/big/ratconv.go
index 941139e..ac3c8bd 100644
--- a/libgo/go/math/big/ratconv.go
+++ b/libgo/go/math/big/ratconv.go
@@ -51,7 +51,8 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
// An optional base-10 ``e'' or base-2 ``p'' (or their upper-case variants)
// exponent may be provided as well, except for hexadecimal floats which
// only accept an (optional) ``p'' exponent (because an ``e'' or ``E'' cannot
-// be distinguished from a mantissa digit).
+// be distinguished from a mantissa digit). If the exponent's absolute value
+// is too large, the operation may fail.
// The entire string, not just a prefix, must be valid for success. If the
// operation failed, the value of z is undefined but the returned value is nil.
func (z *Rat) SetString(s string) (*Rat, bool) {
@@ -169,6 +170,9 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
if n < 0 {
n = -n
}
+ if n > 1e6 {
+ return nil, false // avoid excessively large exponents
+ }
pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs
if exp5 > 0 {
z.a.abs = z.a.abs.mul(z.a.abs, pow5)
@@ -181,15 +185,12 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
}
// apply exp2 contributions
+ if exp2 < -1e7 || exp2 > 1e7 {
+ return nil, false // avoid excessively large exponents
+ }
if exp2 > 0 {
- if int64(uint(exp2)) != exp2 {
- panic("exponent too large")
- }
z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2))
} else if exp2 < 0 {
- if int64(uint(-exp2)) != -exp2 {
- panic("exponent too large")
- }
z.b.abs = z.b.abs.shl(z.b.abs, uint(-exp2))
}
diff --git a/libgo/go/math/big/ratconv_test.go b/libgo/go/math/big/ratconv_test.go
index ba0d1ba..15d206c 100644
--- a/libgo/go/math/big/ratconv_test.go
+++ b/libgo/go/math/big/ratconv_test.go
@@ -589,3 +589,28 @@ func TestIssue31184(t *testing.T) {
}
}
}
+
+func TestIssue45910(t *testing.T) {
+ var x Rat
+ for _, test := range []struct {
+ input string
+ want bool
+ }{
+ {"1e-1000001", false},
+ {"1e-1000000", true},
+ {"1e+1000000", true},
+ {"1e+1000001", false},
+
+ {"0p1000000000000", true},
+ {"1p-10000001", false},
+ {"1p-10000000", true},
+ {"1p+10000000", true},
+ {"1p+10000001", false},
+ {"1.770p02041010010011001001", false}, // test case from issue
+ } {
+ _, got := x.SetString(test.input)
+ if got != test.want {
+ t.Errorf("SetString(%s) got ok = %v; want %v", test.input, got, test.want)
+ }
+ }
+}
diff --git a/libgo/go/net/dnsclient_unix_test.go b/libgo/go/net/dnsclient_unix_test.go
index f57f231..3c9ada3 100644
--- a/libgo/go/net/dnsclient_unix_test.go
+++ b/libgo/go/net/dnsclient_unix_test.go
@@ -1798,3 +1798,161 @@ func TestPTRandNonPTR(t *testing.T) {
t.Errorf("names = %q; want %q", names, want)
}
}
+
+func TestCVE202133195(t *testing.T) {
+ fake := fakeDNSServer{
+ rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+ r := dnsmessage.Message{
+ Header: dnsmessage.Header{
+ ID: q.Header.ID,
+ Response: true,
+ RCode: dnsmessage.RCodeSuccess,
+ RecursionAvailable: true,
+ },
+ Questions: q.Questions,
+ }
+ switch q.Questions[0].Type {
+ case dnsmessage.TypeCNAME:
+ r.Answers = []dnsmessage.Resource{}
+ case dnsmessage.TypeA: // CNAME lookup uses a A/AAAA as a proxy
+ r.Answers = append(r.Answers,
+ dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
+ Type: dnsmessage.TypeA,
+ Class: dnsmessage.ClassINET,
+ Length: 4,
+ },
+ Body: &dnsmessage.AResource{
+ A: TestAddr,
+ },
+ },
+ )
+ case dnsmessage.TypeSRV:
+ n := q.Questions[0].Name
+ if n.String() == "_hdr._tcp.golang.org." {
+ n = dnsmessage.MustNewName("<html>.golang.org.")
+ }
+ r.Answers = append(r.Answers,
+ dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: n,
+ Type: dnsmessage.TypeSRV,
+ Class: dnsmessage.ClassINET,
+ Length: 4,
+ },
+ Body: &dnsmessage.SRVResource{
+ Target: dnsmessage.MustNewName("<html>.golang.org."),
+ },
+ },
+ )
+ case dnsmessage.TypeMX:
+ r.Answers = append(r.Answers,
+ dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
+ Type: dnsmessage.TypeMX,
+ Class: dnsmessage.ClassINET,
+ Length: 4,
+ },
+ Body: &dnsmessage.MXResource{
+ MX: dnsmessage.MustNewName("<html>.golang.org."),
+ },
+ },
+ )
+ case dnsmessage.TypeNS:
+ r.Answers = append(r.Answers,
+ dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
+ Type: dnsmessage.TypeNS,
+ Class: dnsmessage.ClassINET,
+ Length: 4,
+ },
+ Body: &dnsmessage.NSResource{
+ NS: dnsmessage.MustNewName("<html>.golang.org."),
+ },
+ },
+ )
+ case dnsmessage.TypePTR:
+ r.Answers = append(r.Answers,
+ dnsmessage.Resource{
+ Header: dnsmessage.ResourceHeader{
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
+ Type: dnsmessage.TypePTR,
+ Class: dnsmessage.ClassINET,
+ Length: 4,
+ },
+ Body: &dnsmessage.PTRResource{
+ PTR: dnsmessage.MustNewName("<html>.golang.org."),
+ },
+ },
+ )
+ }
+ return r, nil
+ },
+ }
+
+ r := Resolver{PreferGo: true, Dial: fake.DialContext}
+ // Change the default resolver to match our manipulated resolver
+ originalDefault := DefaultResolver
+ DefaultResolver = &r
+ defer func() { DefaultResolver = originalDefault }()
+ // Redirect host file lookups.
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/hosts"
+
+ _, err := r.LookupCNAME(context.Background(), "golang.org")
+ if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err, expected)
+ }
+ _, err = LookupCNAME("golang.org")
+ if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err, expected)
+ }
+
+ _, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
+ if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
+ }
+ _, _, err = LookupSRV("target", "tcp", "golang.org")
+ if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
+ }
+
+ _, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org")
+ if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected)
+ }
+ _, _, err = LookupSRV("hdr", "tcp", "golang.org")
+ if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected)
+ }
+
+ _, err = r.LookupMX(context.Background(), "golang.org")
+ if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err, expected)
+ }
+ _, err = LookupMX("golang.org")
+ if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("LookupMX returned unexpected error, got %q, want %q", err, expected)
+ }
+
+ _, err = r.LookupNS(context.Background(), "golang.org")
+ if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err, expected)
+ }
+ _, err = LookupNS("golang.org")
+ if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("LookupNS returned unexpected error, got %q, want %q", err, expected)
+ }
+
+ _, err = r.LookupAddr(context.Background(), "192.0.2.42")
+ if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err, expected)
+ }
+ _, err = LookupAddr("192.0.2.42")
+ if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected {
+ t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected)
+ }
+}
diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go
index 4e36958..ccb8456 100644
--- a/libgo/go/net/http/httputil/reverseproxy.go
+++ b/libgo/go/net/http/httputil/reverseproxy.go
@@ -248,22 +248,18 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// important is "Connection" because we want a persistent
// connection, regardless of what the client sent to us.
for _, h := range hopHeaders {
- hv := outreq.Header.Get(h)
- if hv == "" {
- continue
- }
- if h == "Te" && hv == "trailers" {
- // Issue 21096: tell backend applications that
- // care about trailer support that we support
- // trailers. (We do, but we don't go out of
- // our way to advertise that unless the
- // incoming client request thought it was
- // worth mentioning)
- continue
- }
outreq.Header.Del(h)
}
+ // Issue 21096: tell backend applications that care about trailer support
+ // that we support trailers. (We do, but we don't go out of our way to
+ // advertise that unless the incoming client request thought it was worth
+ // mentioning.) Note that we look at req.Header, not outreq.Header, since
+ // the latter has passed through removeConnectionHeaders.
+ if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") {
+ outreq.Header.Set("Te", "trailers")
+ }
+
// After stripping all the hop-by-hop connection headers above, add back any
// necessary for protocol upgrades, such as for websockets.
if reqUpType != "" {
diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go
index 3acbd94..3211463 100644
--- a/libgo/go/net/http/httputil/reverseproxy_test.go
+++ b/libgo/go/net/http/httputil/reverseproxy_test.go
@@ -90,8 +90,9 @@ func TestReverseProxy(t *testing.T) {
getReq, _ := http.NewRequest("GET", frontend.URL, nil)
getReq.Host = "some-name"
- getReq.Header.Set("Connection", "close")
- getReq.Header.Set("Te", "trailers")
+ getReq.Header.Set("Connection", "close, TE")
+ getReq.Header.Add("Te", "foo")
+ getReq.Header.Add("Te", "bar, trailers")
getReq.Header.Set("Proxy-Connection", "should be deleted")
getReq.Header.Set("Upgrade", "foo")
getReq.Close = true
@@ -235,6 +236,64 @@ func TestReverseProxyStripHeadersPresentInConnection(t *testing.T) {
}
}
+func TestReverseProxyStripEmptyConnection(t *testing.T) {
+ // See Issue 46313.
+ const backendResponse = "I am the backend"
+
+ // someConnHeader is some arbitrary header to be declared as a hop-by-hop header
+ // in the Request's Connection header.
+ const someConnHeader = "X-Some-Conn-Header"
+
+ backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if c := r.Header.Values("Connection"); len(c) != 0 {
+ t.Errorf("handler got header %q = %v; want empty", "Connection", c)
+ }
+ if c := r.Header.Get(someConnHeader); c != "" {
+ t.Errorf("handler got header %q = %q; want empty", someConnHeader, c)
+ }
+ w.Header().Add("Connection", "")
+ w.Header().Add("Connection", someConnHeader)
+ w.Header().Set(someConnHeader, "should be deleted")
+ io.WriteString(w, backendResponse)
+ }))
+ defer backend.Close()
+ backendURL, err := url.Parse(backend.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ proxyHandler := NewSingleHostReverseProxy(backendURL)
+ frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ proxyHandler.ServeHTTP(w, r)
+ if c := r.Header.Get(someConnHeader); c != "should be deleted" {
+ t.Errorf("handler modified header %q = %q; want %q", someConnHeader, c, "should be deleted")
+ }
+ }))
+ defer frontend.Close()
+
+ getReq, _ := http.NewRequest("GET", frontend.URL, nil)
+ getReq.Header.Add("Connection", "")
+ getReq.Header.Add("Connection", someConnHeader)
+ getReq.Header.Set(someConnHeader, "should be deleted")
+ res, err := frontend.Client().Do(getReq)
+ if err != nil {
+ t.Fatalf("Get: %v", err)
+ }
+ defer res.Body.Close()
+ bodyBytes, err := io.ReadAll(res.Body)
+ if err != nil {
+ t.Fatalf("reading body: %v", err)
+ }
+ if got, want := string(bodyBytes), backendResponse; got != want {
+ t.Errorf("got body %q; want %q", got, want)
+ }
+ if c := res.Header.Get("Connection"); c != "" {
+ t.Errorf("handler got header %q = %q; want empty", "Connection", c)
+ }
+ if c := res.Header.Get(someConnHeader); c != "" {
+ t.Errorf("handler got header %q = %q; want empty", someConnHeader, c)
+ }
+}
+
func TestXForwardedFor(t *testing.T) {
const prevForwardedFor = "client ip"
const backendResponse = "I am the backend"
diff --git a/libgo/go/net/http/transport_test.go b/libgo/go/net/http/transport_test.go
index cf1f511..d0202c0 100644
--- a/libgo/go/net/http/transport_test.go
+++ b/libgo/go/net/http/transport_test.go
@@ -5318,7 +5318,6 @@ func TestMissingStatusNoPanic(t *testing.T) {
ln := newLocalListener(t)
addr := ln.Addr().String()
- shutdown := make(chan bool, 1)
done := make(chan bool)
fullAddrURL := fmt.Sprintf("http://%s", addr)
raw := "HTTP/1.1 400\r\n" +
@@ -5330,10 +5329,7 @@ func TestMissingStatusNoPanic(t *testing.T) {
"Aloha Olaa"
go func() {
- defer func() {
- ln.Close()
- close(done)
- }()
+ defer close(done)
conn, _ := ln.Accept()
if conn != nil {
@@ -5364,7 +5360,7 @@ func TestMissingStatusNoPanic(t *testing.T) {
t.Errorf("got=%v want=%q", err, want)
}
- close(shutdown)
+ ln.Close()
<-done
}
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go
index 5f71198..0660268 100644
--- a/libgo/go/net/lookup.go
+++ b/libgo/go/net/lookup.go
@@ -389,8 +389,11 @@ func (r *Resolver) LookupPort(ctx context.Context, network, service string) (por
// LookupCNAME does not return an error if host does not
// contain DNS "CNAME" records, as long as host resolves to
// address records.
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
func LookupCNAME(host string) (cname string, err error) {
- return DefaultResolver.lookupCNAME(context.Background(), host)
+ return DefaultResolver.LookupCNAME(context.Background(), host)
}
// LookupCNAME returns the canonical name for the given host.
@@ -403,8 +406,18 @@ func LookupCNAME(host string) (cname string, err error) {
// LookupCNAME does not return an error if host does not
// contain DNS "CNAME" records, as long as host resolves to
// address records.
-func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string, err error) {
- return r.lookupCNAME(ctx, host)
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
+func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) {
+ cname, err := r.lookupCNAME(ctx, host)
+ if err != nil {
+ return "", err
+ }
+ if !isDomainName(cname) {
+ return "", &DNSError{Err: "CNAME target is invalid", Name: host}
+ }
+ return cname, nil
}
// LookupSRV tries to resolve an SRV query of the given service,
@@ -416,8 +429,11 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string,
// That is, it looks up _service._proto.name. To accommodate services
// publishing SRV records under non-standard names, if both service
// and proto are empty strings, LookupSRV looks up name directly.
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names.
func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
- return DefaultResolver.lookupSRV(context.Background(), service, proto, name)
+ return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
}
// LookupSRV tries to resolve an SRV query of the given service,
@@ -429,28 +445,82 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err err
// That is, it looks up _service._proto.name. To accommodate services
// publishing SRV records under non-standard names, if both service
// and proto are empty strings, LookupSRV looks up name directly.
-func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*SRV, err error) {
- return r.lookupSRV(ctx, service, proto, name)
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names.
+func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
+ cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
+ if err != nil {
+ return "", nil, err
+ }
+ if cname != "" && !isDomainName(cname) {
+ return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
+ }
+ for _, addr := range addrs {
+ if addr == nil {
+ continue
+ }
+ if !isDomainName(addr.Target) {
+ return "", nil, &DNSError{Err: "SRV target is invalid", Name: name}
+ }
+ }
+ return cname, addrs, nil
}
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
+//
+// The returned mail server names are validated to be properly
+// formatted presentation-format domain names.
func LookupMX(name string) ([]*MX, error) {
- return DefaultResolver.lookupMX(context.Background(), name)
+ return DefaultResolver.LookupMX(context.Background(), name)
}
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
+//
+// The returned mail server names are validated to be properly
+// formatted presentation-format domain names.
func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
- return r.lookupMX(ctx, name)
+ records, err := r.lookupMX(ctx, name)
+ if err != nil {
+ return nil, err
+ }
+ for _, mx := range records {
+ if mx == nil {
+ continue
+ }
+ if !isDomainName(mx.Host) {
+ return nil, &DNSError{Err: "MX target is invalid", Name: name}
+ }
+ }
+ return records, nil
}
// LookupNS returns the DNS NS records for the given domain name.
+//
+// The returned name server names are validated to be properly
+// formatted presentation-format domain names.
func LookupNS(name string) ([]*NS, error) {
- return DefaultResolver.lookupNS(context.Background(), name)
+ return DefaultResolver.LookupNS(context.Background(), name)
}
// LookupNS returns the DNS NS records for the given domain name.
+//
+// The returned name server names are validated to be properly
+// formatted presentation-format domain names.
func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
- return r.lookupNS(ctx, name)
+ records, err := r.lookupNS(ctx, name)
+ if err != nil {
+ return nil, err
+ }
+ for _, ns := range records {
+ if ns == nil {
+ continue
+ }
+ if !isDomainName(ns.Host) {
+ return nil, &DNSError{Err: "NS target is invalid", Name: name}
+ }
+ }
+ return records, nil
}
// LookupTXT returns the DNS TXT records for the given domain name.
@@ -466,14 +536,29 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)
// LookupAddr performs a reverse lookup for the given address, returning a list
// of names mapping to that address.
//
+// The returned names are validated to be properly formatted presentation-format
+// domain names.
+//
// When using the host C library resolver, at most one result will be
// returned. To bypass the host resolver, use a custom Resolver.
func LookupAddr(addr string) (names []string, err error) {
- return DefaultResolver.lookupAddr(context.Background(), addr)
+ return DefaultResolver.LookupAddr(context.Background(), addr)
}
// LookupAddr performs a reverse lookup for the given address, returning a list
// of names mapping to that address.
-func (r *Resolver) LookupAddr(ctx context.Context, addr string) (names []string, err error) {
- return r.lookupAddr(ctx, addr)
+//
+// The returned names are validated to be properly formatted presentation-format
+// domain names.
+func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
+ names, err := r.lookupAddr(ctx, addr)
+ if err != nil {
+ return nil, err
+ }
+ for _, name := range names {
+ if !isDomainName(name) {
+ return nil, &DNSError{Err: "PTR target is invalid", Name: addr}
+ }
+ }
+ return names, nil
}
diff --git a/libgo/go/os/signal/signal_test.go b/libgo/go/os/signal/signal_test.go
index db94756..1f89780 100644
--- a/libgo/go/os/signal/signal_test.go
+++ b/libgo/go/os/signal/signal_test.go
@@ -15,6 +15,7 @@ import (
"os"
"os/exec"
"runtime"
+ "runtime/trace"
"strconv"
"sync"
"syscall"
@@ -853,3 +854,44 @@ func TestNotifyContextStringer(t *testing.T) {
t.Errorf("c.String() = %q, want %q", got, want)
}
}
+
+// #44193 test signal handling while stopping and starting the world.
+func TestSignalTrace(t *testing.T) {
+ done := make(chan struct{})
+ quit := make(chan struct{})
+ c := make(chan os.Signal, 1)
+ Notify(c, syscall.SIGHUP)
+
+ // Source and sink for signals busy loop unsynchronized with
+ // trace starts and stops. We are ultimately validating that
+ // signals and runtime.(stop|start)TheWorldGC are compatible.
+ go func() {
+ defer close(done)
+ defer Stop(c)
+ pid := syscall.Getpid()
+ for {
+ select {
+ case <-quit:
+ return
+ default:
+ syscall.Kill(pid, syscall.SIGHUP)
+ }
+ waitSig(t, c, syscall.SIGHUP)
+ }
+ }()
+
+ for i := 0; i < 100; i++ {
+ buf := new(bytes.Buffer)
+ if err := trace.Start(buf); err != nil {
+ t.Fatalf("[%d] failed to start tracing: %v", i, err)
+ }
+ time.After(1 * time.Microsecond)
+ trace.Stop()
+ size := buf.Len()
+ if size == 0 {
+ t.Fatalf("[%d] trace is empty", i)
+ }
+ }
+ close(quit)
+ <-done
+}
diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go
index 42411e9..73d7aaa 100644
--- a/libgo/go/runtime/pprof/pprof_test.go
+++ b/libgo/go/runtime/pprof/pprof_test.go
@@ -279,7 +279,8 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri
broken := false
switch runtime.GOOS {
- case "darwin", "ios", "dragonfly", "netbsd", "illumos", "solaris":
+ // See https://golang.org/issue/45170 for AIX.
+ case "darwin", "ios", "dragonfly", "netbsd", "illumos", "solaris", "aix":
broken = true
case "openbsd":
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index eec44db..037e779 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -1287,6 +1287,9 @@ func mPark() {
g := getg()
for {
notesleep(&g.m.park)
+ // Note, because of signal handling by this parked m,
+ // a preemptive mDoFixup() may actually occur via
+ // mDoFixupAndOSYield(). (See golang.org/issue/44193)
noteclear(&g.m.park)
if !mDoFixup() {
return
@@ -1949,9 +1952,21 @@ var mFixupRace struct {
// mDoFixup runs any outstanding fixup function for the running m.
// Returns true if a fixup was outstanding and actually executed.
//
+// Note: to avoid deadlocks, and the need for the fixup function
+// itself to be async safe, signals are blocked for the working m
+// while it holds the mFixup lock. (See golang.org/issue/44193)
+//
//go:nosplit
func mDoFixup() bool {
_g_ := getg()
+ if used := atomic.Load(&_g_.m.mFixup.used); used == 0 {
+ return false
+ }
+
+ // slow path - if fixup fn is used, block signals and lock.
+ var sigmask sigset
+ sigsave(&sigmask)
+ sigblock(false)
lock(&_g_.m.mFixup.lock)
fn := _g_.m.mFixup.fn
if fn != nil {
@@ -1972,9 +1987,20 @@ func mDoFixup() bool {
fn(false)
}
unlock(&_g_.m.mFixup.lock)
+ msigrestore(sigmask)
return fn != nil
}
+// mDoFixupAndOSYield is called when an m is unable to send a signal
+// because the allThreadsSyscall mechanism is in progress. That is, an
+// mPark() has been interrupted with this signal handler so we need to
+// ensure the fixup is executed from this context.
+//go:nosplit
+func mDoFixupAndOSYield() {
+ mDoFixup()
+ osyield()
+}
+
// templateThread is a thread in a known-good state that exists solely
// to start new threads in known-good states when the calling thread
// may not be in a good state.
diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go
index 4b13cfc..1879b82 100644
--- a/libgo/go/runtime/runtime2.go
+++ b/libgo/go/runtime/runtime2.go
@@ -584,10 +584,13 @@ type m struct {
syscalltick uint32
freelink *m // on sched.freem
- // mFixup is used to synchronize OS related m state (credentials etc)
- // use mutex to access.
+ // mFixup is used to synchronize OS related m state
+ // (credentials etc) use mutex to access. To avoid deadlocks
+ // an atomic.Load() of used being zero in mDoFixupFn()
+ // guarantees fn is nil.
mFixup struct {
lock mutex
+ used uint32
fn func(bool) bool
}
diff --git a/libgo/go/runtime/sigqueue.go b/libgo/go/runtime/sigqueue.go
index ca41b05..7ca7557 100644
--- a/libgo/go/runtime/sigqueue.go
+++ b/libgo/go/runtime/sigqueue.go
@@ -119,7 +119,7 @@ Send:
}
case sigFixup:
// nothing to do - we need to wait for sigIdle.
- osyield()
+ mDoFixupAndOSYield()
}
}
diff --git a/libgo/go/time/zoneinfo.go b/libgo/go/time/zoneinfo.go
index 6db9443..5705233 100644
--- a/libgo/go/time/zoneinfo.go
+++ b/libgo/go/time/zoneinfo.go
@@ -178,7 +178,7 @@ func (l *Location) lookup(sec int64) (name string, offset int, start, end int64)
// If we're at the end of the known zone transitions,
// try the extend string.
if lo == len(tx)-1 && l.extend != "" {
- if ename, eoffset, estart, eend, ok := tzset(l.extend, end, sec); ok {
+ if ename, eoffset, estart, eend, _, ok := tzset(l.extend, end, sec); ok {
return ename, eoffset, estart, eend
}
}
@@ -244,7 +244,7 @@ func (l *Location) firstZoneUsed() bool {
// We call this a tzset string since in C the function tzset reads TZ.
// The return values are as for lookup, plus ok which reports whether the
// parse succeeded.
-func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, ok bool) {
+func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, isDST, ok bool) {
var (
stdName, dstName string
stdOffset, dstOffset int
@@ -255,7 +255,7 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
stdOffset, s, ok = tzsetOffset(s)
}
if !ok {
- return "", 0, 0, 0, false
+ return "", 0, 0, 0, false, false
}
// The numbers in the tzset string are added to local time to get UTC,
@@ -265,7 +265,7 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
if len(s) == 0 || s[0] == ',' {
// No daylight savings time.
- return stdName, stdOffset, initEnd, omega, true
+ return stdName, stdOffset, initEnd, omega, false, true
}
dstName, s, ok = tzsetName(s)
@@ -278,7 +278,7 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
}
}
if !ok {
- return "", 0, 0, 0, false
+ return "", 0, 0, 0, false, false
}
if len(s) == 0 {
@@ -287,19 +287,19 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
}
// The TZ definition does not mention ';' here but tzcode accepts it.
if s[0] != ',' && s[0] != ';' {
- return "", 0, 0, 0, false
+ return "", 0, 0, 0, false, false
}
s = s[1:]
var startRule, endRule rule
startRule, s, ok = tzsetRule(s)
if !ok || len(s) == 0 || s[0] != ',' {
- return "", 0, 0, 0, false
+ return "", 0, 0, 0, false, false
}
s = s[1:]
endRule, s, ok = tzsetRule(s)
if !ok || len(s) > 0 {
- return "", 0, 0, 0, false
+ return "", 0, 0, 0, false, false
}
year, _, _, yday := absDate(uint64(sec+unixToInternal+internalToAbsolute), false)
@@ -313,10 +313,15 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
startSec := int64(tzruleTime(year, startRule, stdOffset))
endSec := int64(tzruleTime(year, endRule, dstOffset))
+ dstIsDST, stdIsDST := true, false
+ // Note: this is a flipping of "DST" and "STD" while retaining the labels
+ // This happens in southern hemispheres. The labelling here thus is a little
+ // inconsistent with the goal.
if endSec < startSec {
startSec, endSec = endSec, startSec
stdName, dstName = dstName, stdName
stdOffset, dstOffset = dstOffset, stdOffset
+ stdIsDST, dstIsDST = dstIsDST, stdIsDST
}
// The start and end values that we return are accurate
@@ -324,11 +329,11 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
// just the start and end of the year. That suffices for
// the only caller that cares, which is Date.
if ysec < startSec {
- return stdName, stdOffset, abs, startSec + abs, true
+ return stdName, stdOffset, abs, startSec + abs, stdIsDST, true
} else if ysec >= endSec {
- return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, true
+ return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, stdIsDST, true
} else {
- return dstName, dstOffset, startSec + abs, endSec + abs, true
+ return dstName, dstOffset, startSec + abs, endSec + abs, dstIsDST, true
}
}
diff --git a/libgo/go/time/zoneinfo_read.go b/libgo/go/time/zoneinfo_read.go
index 463e420..c8c7256 100644
--- a/libgo/go/time/zoneinfo_read.go
+++ b/libgo/go/time/zoneinfo_read.go
@@ -249,8 +249,8 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
// This also avoids a panic later when we add and then use a fake transition (golang.org/issue/29437).
return nil, badData
}
- zone := make([]zone, nzone)
- for i := range zone {
+ zones := make([]zone, nzone)
+ for i := range zones {
var ok bool
var n uint32
if n, ok = zonedata.big4(); !ok {
@@ -259,22 +259,22 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
if uint32(int(n)) != n {
return nil, badData
}
- zone[i].offset = int(int32(n))
+ zones[i].offset = int(int32(n))
var b byte
if b, ok = zonedata.byte(); !ok {
return nil, badData
}
- zone[i].isDST = b != 0
+ zones[i].isDST = b != 0
if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
return nil, badData
}
- zone[i].name = byteString(abbrev[b:])
+ zones[i].name = byteString(abbrev[b:])
if runtime.GOOS == "aix" && len(name) > 8 && (name[:8] == "Etc/GMT+" || name[:8] == "Etc/GMT-") {
// There is a bug with AIX 7.2 TL 0 with files in Etc,
// GMT+1 will return GMT-1 instead of GMT+1 or -01.
if name != "Etc/GMT+0" {
// GMT+0 is OK
- zone[i].name = name[4:]
+ zones[i].name = name[4:]
}
}
}
@@ -297,7 +297,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
}
}
tx[i].when = n
- if int(txzones[i]) >= len(zone) {
+ if int(txzones[i]) >= len(zones) {
return nil, badData
}
tx[i].index = txzones[i]
@@ -316,7 +316,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
}
// Committed to succeed.
- l := &Location{zone: zone, tx: tx, name: name, extend: extend}
+ l := &Location{zone: zones, tx: tx, name: name, extend: extend}
// Fill in the cache with information about right now,
// since that will be the most common lookup.
@@ -325,26 +325,27 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
l.cacheStart = tx[i].when
l.cacheEnd = omega
- zoneIdx := tx[i].index
+ l.cacheZone = &l.zone[tx[i].index]
if i+1 < len(tx) {
l.cacheEnd = tx[i+1].when
} else if l.extend != "" {
// If we're at the end of the known zone transitions,
// try the extend string.
- if name, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
+ if name, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheEnd, sec); ok {
l.cacheStart = estart
l.cacheEnd = eend
- // Find the zone that is returned by tzset,
- // the last transition is not always the correct zone.
- for i, z := range l.zone {
- if z.name == name {
- zoneIdx = uint8(i)
- break
+ // Find the zone that is returned by tzset to avoid allocation if possible.
+ if zoneIdx := findZone(l.zone, name, offset, isDST); zoneIdx != -1 {
+ l.cacheZone = &l.zone[zoneIdx]
+ } else {
+ l.cacheZone = &zone{
+ name: name,
+ offset: offset,
+ isDST: isDST,
}
}
}
}
- l.cacheZone = &l.zone[zoneIdx]
break
}
}
@@ -352,6 +353,15 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
return l, nil
}
+func findZone(zones []zone, name string, offset int, isDST bool) int {
+ for i, z := range zones {
+ if z.name == name && z.offset == offset && z.isDST == isDST {
+ return i
+ }
+ }
+ return -1
+}
+
// loadTzinfoFromDirOrZip returns the contents of the file with the given name
// in dir. dir can either be an uncompressed zip file, or a directory.
func loadTzinfoFromDirOrZip(dir, name string) ([]byte, error) {
diff --git a/libgo/go/time/zoneinfo_test.go b/libgo/go/time/zoneinfo_test.go
index 3e32da0..a9b4f07 100644
--- a/libgo/go/time/zoneinfo_test.go
+++ b/libgo/go/time/zoneinfo_test.go
@@ -192,6 +192,7 @@ func TestMalformedTZData(t *testing.T) {
var slimTests = []struct {
zoneName string
tzData string
+ date func(*time.Location) time.Time
wantName string
wantOffset int
}{
@@ -199,6 +200,7 @@ var slimTests = []struct {
// 2020b slim tzdata for Europe/Berlin.
zoneName: "Europe/Berlin",
tzData: "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n",
+ date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
wantName: "CET",
wantOffset: 3600,
},
@@ -206,6 +208,7 @@ var slimTests = []struct {
// 2021a slim tzdata for America/Nuuk.
zoneName: "America/Nuuk",
tzData: "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\n<-03>3<-02>,M3.5.0/-2,M10.5.0/-1\n",
+ date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
wantName: "-03",
wantOffset: -10800,
},
@@ -213,9 +216,18 @@ var slimTests = []struct {
// 2021a slim tzdata for Asia/Gaza.
zoneName: "Asia/Gaza",
tzData: "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/48,M10.4.4/49\n",
+ date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
wantName: "EET",
wantOffset: 7200,
},
+ {
+ // 2021a slim tzdata for Europe/Dublin.
+ zoneName: "Europe/Dublin",
+ tzData: "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\x08\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xdc\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\x0b\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4\xc3\xa0\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba\x20\xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c\x20\xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb\x20\xff\xff\xff\xff\xa6%`\x20\xff\xff\xff\xff\xa7'\xc6\x20\xff\xff\xff\xff\xa8*,\x20\xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15\x20\xff\xff\xff\xff\xab\xe9\xf0\x20\xff\xff\xff\xff\xac\xc7l\x20\xff\xff\xff\xff\xad\xc9\xd2\x20\xff\xff\xff\xff\xae\xa7N\x20\xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870\x20\xff\xff\xff\xff\xb1\x92\xd0\xa0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ\x20\xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xef\xd4\xa0\xff\xff\xff\xff\xba\xe9\x00\x20\xff\xff\xff\xff\xbb\xd8\xf1\x20\xff\xff\xff\xff\xbc\xdbW\x20\xff\xff\xff\xff\xbd\xb8\xd3\x20\xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5\x20\xff\xff\xff\xff\xc0\x9b\x1b\x20\xff\xff\xff\xff\xc1x\x97\x20\xff\xff\xff\xff\xc2z\xfd\x20\xff\xff\xff\xff\xc3Xy\x20\xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[\x20\xff\xff\xff\xff\xc6:\xc1\x20\xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xd4I\xe0\x20\xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac\x20\xff\xff\xff\xff\xd7,(\x20\xff\xff\xff\xff\xd8.\x8e\x20\xff\xff\xff\xff\xd8\xf9\x95\x20\xff\xff\xff\xff\xda\x0ep\x20\xff\xff\xff\xff\xda\xeb\xec\x20\xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce\x20\xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16\x20\xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt\x20\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\x0c\xa0\xff\xff\xff\xff\xe6=\xad\x20\xff\xff\xff\xff\xe7\x1b)\x20\xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b\x20\xff\xff\xff\xff\xe9\xfdq\x20\xff\xff\xff\xff\xea\xda\xed\x20\xff\xff\xff\xff\xeb\xddS\x20\xff\xff\xff\xff\xec\xba\xcf\x20\xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1\x20\xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f}\x20\xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_\x20\xff\xff\xff\xff\xf3Jf\x20\xff\xff\xff\xff\xf4_A\x20\xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?#\x20\xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05\x20\xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7\x20\xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfd\xc7\xbbp\x00\x00\x00\x00\x03p\xc6\x20\x00\x00\x00\x00\x04)X\x20\x00\x00\x00\x00\x05P\xa8\x20\x00\x00\x00\x00\x06\x09:\x20\x00\x00\x00\x00\x070\x8a\x20\x00\x00\x00\x00\x07\xe9\x1c\x20\x00\x00\x00\x00\x09\x10l\x20\x00\x00\x00\x00\x09\xc8\xfe\x20\x00\x00\x00\x00\n\xf0N\x20\x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00\x20\x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12\x20\x00\x00\x00\x00\x0fq\xde\xa0\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168\xc6\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1a\xc3\x91\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00\x20lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9\xd3\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\x08\x1f\x01\x08\x00\x00\x0e\x10\x01\x0c\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\x08\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\x08LMT\x00DMT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\n",
+ date: func(loc *time.Location) time.Time { return time.Date(2021, time.April, 2, 11, 12, 13, 0, loc) },
+ wantName: "IST",
+ wantOffset: 3600,
+ },
}
func TestLoadLocationFromTZDataSlim(t *testing.T) {
@@ -225,7 +237,7 @@ func TestLoadLocationFromTZDataSlim(t *testing.T) {
t.Fatal(err)
}
- d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
+ d := test.date(reference)
tzName, tzOffset := d.Zone()
if tzName != test.wantName {
t.Errorf("Zone name == %s, want %s", tzName, test.wantName)
@@ -245,20 +257,21 @@ func TestTzset(t *testing.T) {
off int
start int64
end int64
+ isDST bool
ok bool
}{
- {"", 0, 0, "", 0, 0, 0, false},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, true},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, true},
- {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, true},
+ {"", 0, 0, "", 0, 0, 0, false, false},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, false, true},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
+ {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
} {
- name, off, start, end, ok := time.Tzset(test.inStr, test.inEnd, test.inSec)
- if name != test.name || off != test.off || start != test.start || end != test.end || ok != test.ok {
- t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, want %q, %d, %d, %d, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, ok, test.name, test.off, test.start, test.end, test.ok)
+ name, off, start, end, isDST, ok := time.Tzset(test.inStr, test.inEnd, test.inSec)
+ if name != test.name || off != test.off || start != test.start || end != test.end || isDST != test.isDST || ok != test.ok {
+ t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, %t, want %q, %d, %d, %d, %t, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, isDST, ok, test.name, test.off, test.start, test.end, test.isDST, test.ok)
}
}
}
diff --git a/libgo/go/vendor/modules.txt b/libgo/go/vendor/modules.txt
index 04bb67e..b18d366 100644
--- a/libgo/go/vendor/modules.txt
+++ b/libgo/go/vendor/modules.txt
@@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519
golang.org/x/crypto/hkdf
golang.org/x/crypto/internal/subtle
golang.org/x/crypto/poly1305
-# golang.org/x/net v0.0.0-20201209123823-ac852fbbde11
+# golang.org/x/net v0.0.0-20210428183300-3f4a416c7d3b
## explicit
golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 255c160..ed9f258 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,36 @@
+2021-06-10 Andrew Stubbs <ams@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * libgomp.map (GOACC_2.0.2): New symbol version.
+ * libgomp_g.h (GOACC_enter_data, GOACC_exit_data) New prototypes.
+ * oacc-mem.c (GOACC_enter_data, GOACC_exit_data) New functions.
+
+2021-06-10 Thomas Schwinge <thomas@codesourcery.com>
+ Andrew Stubbs <ams@codesourcery.com>
+
+ * oacc-mem.c (goacc_enter_exit_data_internal): New function,
+ extracted from...
+ (GOACC_enter_exit_data): ... here.
+ (GOACC_declare): Use it.
+
+2021-06-10 Thomas Schwinge <thomas@codesourcery.com>
+
+ * oacc-parallel.c (GOACC_declare): Move...
+ * oacc-mem.c: ... here.
+ * libgomp_g.h: Adjust.
+
+2021-06-10 Andrew Stubbs <ams@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * oacc-parallel.c (GOACC_declare): Clean up 'GOMP_MAP_POINTER'
+ handling.
+
+2021-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/100981
+ * testsuite/libgomp.fortran/pr100981-2.f90 (cdcdot): Initialize
+ dsdotr and dsdoti to 0.
+
2021-06-09 H.J. Lu <hjl.tools@gmail.com>
* testsuite/lib/libgomp.exp (libgomp_init): Don't add -march=i486
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index 4ad190a..8ea27b5 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -541,6 +541,12 @@ GOACC_2.0.1 {
GOACC_parallel_keyed;
} GOACC_2.0;
+GOACC_2.0.2 {
+ global:
+ GOACC_enter_data;
+ GOACC_exit_data;
+} GOACC_2.0.1;
+
GOMP_PLUGIN_1.0 {
global:
GOMP_PLUGIN_malloc;
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index 3cbe0a4..f890a20 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -370,6 +370,11 @@ extern void GOACC_wait (int, int, ...);
extern void GOACC_enter_exit_data (int, size_t, void **, size_t *,
unsigned short *, int, int, ...);
+extern void GOACC_enter_data (int, size_t, void **, size_t *,
+ unsigned short *, int, int, ...);
+extern void GOACC_exit_data (int, size_t, void **, size_t *,
+ unsigned short *, int, int, ...);
+extern void GOACC_declare (int, size_t, void **, size_t *, unsigned short *);
/* oacc-parallel.c */
@@ -384,6 +389,5 @@ extern void GOACC_update (int, size_t, void **, size_t *,
unsigned short *, int, int, ...);
extern int GOACC_get_num_threads (void);
extern int GOACC_get_thread_num (void);
-extern void GOACC_declare (int, size_t, void **, size_t *, unsigned short *);
#endif /* LIBGOMP_G_H */
diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c
index 405574d..123fe15 100644
--- a/libgomp/oacc-mem.c
+++ b/libgomp/oacc-mem.c
@@ -1320,56 +1320,22 @@ goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum,
gomp_mutex_unlock (&acc_dev->lock);
}
-void
-GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
- size_t *sizes, unsigned short *kinds, int async,
- int num_waits, ...)
+static void
+goacc_enter_exit_data_internal (int flags_m, size_t mapnum, void **hostaddrs,
+ size_t *sizes, unsigned short *kinds,
+ bool data_enter, int async, int num_waits,
+ va_list *ap)
{
int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
struct goacc_thread *thr;
struct gomp_device_descr *acc_dev;
- bool data_enter = false;
- size_t i;
goacc_lazy_initialize ();
thr = goacc_thread ();
acc_dev = thr->dev;
- /* Determine if this is an "acc enter data". */
- for (i = 0; i < mapnum; ++i)
- {
- unsigned char kind = kinds[i] & 0xff;
-
- if (kind == GOMP_MAP_POINTER
- || kind == GOMP_MAP_TO_PSET
- || kind == GOMP_MAP_STRUCT)
- continue;
-
- if (kind == GOMP_MAP_FORCE_ALLOC
- || kind == GOMP_MAP_FORCE_PRESENT
- || kind == GOMP_MAP_ATTACH
- || kind == GOMP_MAP_FORCE_TO
- || kind == GOMP_MAP_TO
- || kind == GOMP_MAP_ALLOC)
- {
- data_enter = true;
- break;
- }
-
- if (kind == GOMP_MAP_RELEASE
- || kind == GOMP_MAP_DELETE
- || kind == GOMP_MAP_DETACH
- || kind == GOMP_MAP_FORCE_DETACH
- || kind == GOMP_MAP_FROM
- || kind == GOMP_MAP_FORCE_FROM)
- break;
-
- gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
- kind);
- }
-
bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
acc_prof_info prof_info;
@@ -1433,13 +1399,7 @@ GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
}
if (num_waits)
- {
- va_list ap;
-
- va_start (ap, num_waits);
- goacc_wait (async, num_waits, &ap);
- va_end (ap);
- }
+ goacc_wait (async, num_waits, ap);
goacc_aq aq = get_goacc_asyncqueue (async);
@@ -1461,3 +1421,123 @@ GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
thr->api_info = NULL;
}
}
+
+/* Legacy entry point (GCC 11 and earlier). */
+
+void
+GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
+ size_t *sizes, unsigned short *kinds, int async,
+ int num_waits, ...)
+{
+ /* Determine if this is an OpenACC "enter data". */
+ bool data_enter = false;
+ for (size_t i = 0; i < mapnum; ++i)
+ {
+ unsigned char kind = kinds[i] & 0xff;
+
+ if (kind == GOMP_MAP_POINTER
+ || kind == GOMP_MAP_TO_PSET
+ || kind == GOMP_MAP_STRUCT)
+ continue;
+
+ if (kind == GOMP_MAP_FORCE_ALLOC
+ || kind == GOMP_MAP_FORCE_PRESENT
+ || kind == GOMP_MAP_ATTACH
+ || kind == GOMP_MAP_FORCE_TO
+ || kind == GOMP_MAP_TO
+ || kind == GOMP_MAP_ALLOC)
+ {
+ data_enter = true;
+ break;
+ }
+
+ if (kind == GOMP_MAP_RELEASE
+ || kind == GOMP_MAP_DELETE
+ || kind == GOMP_MAP_DETACH
+ || kind == GOMP_MAP_FORCE_DETACH
+ || kind == GOMP_MAP_FROM
+ || kind == GOMP_MAP_FORCE_FROM)
+ break;
+
+ gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
+ kind);
+ }
+
+ va_list ap;
+ va_start (ap, num_waits);
+ goacc_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds,
+ data_enter, async, num_waits, &ap);
+ va_end (ap);
+}
+
+void
+GOACC_enter_data (int flags_m, size_t mapnum, void **hostaddrs,
+ size_t *sizes, unsigned short *kinds, int async,
+ int num_waits, ...)
+{
+ va_list ap;
+ va_start (ap, num_waits);
+ goacc_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds,
+ true, async, num_waits, &ap);
+ va_end (ap);
+}
+
+void
+GOACC_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
+ size_t *sizes, unsigned short *kinds, int async,
+ int num_waits, ...)
+{
+ va_list ap;
+ va_start (ap, num_waits);
+ goacc_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds,
+ false, async, num_waits, &ap);
+ va_end (ap);
+}
+
+void
+GOACC_declare (int flags_m, size_t mapnum,
+ void **hostaddrs, size_t *sizes, unsigned short *kinds)
+{
+ for (size_t i = 0; i < mapnum; i++)
+ {
+ unsigned char kind = kinds[i] & 0xff;
+
+ if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
+ continue;
+
+ switch (kind)
+ {
+ case GOMP_MAP_ALLOC:
+ if (acc_is_present (hostaddrs[i], sizes[i]))
+ continue;
+ /* FALLTHRU */
+ case GOMP_MAP_FORCE_ALLOC:
+ case GOMP_MAP_TO:
+ case GOMP_MAP_FORCE_TO:
+ goacc_enter_exit_data_internal (flags_m, 1, &hostaddrs[i], &sizes[i],
+ &kinds[i], true, GOMP_ASYNC_SYNC, 0, NULL);
+ break;
+
+ case GOMP_MAP_FROM:
+ case GOMP_MAP_FORCE_FROM:
+ case GOMP_MAP_RELEASE:
+ case GOMP_MAP_DELETE:
+ goacc_enter_exit_data_internal (flags_m, 1, &hostaddrs[i], &sizes[i],
+ &kinds[i], false, GOMP_ASYNC_SYNC, 0, NULL);
+ break;
+
+ case GOMP_MAP_FORCE_DEVICEPTR:
+ break;
+
+ case GOMP_MAP_FORCE_PRESENT:
+ if (!acc_is_present (hostaddrs[i], sizes[i]))
+ gomp_fatal ("[%p,%ld] is not mapped", hostaddrs[i],
+ (unsigned long) sizes[i]);
+ break;
+
+ default:
+ assert (0);
+ break;
+ }
+ }
+}
diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index cf1baf6..939e09f 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -728,61 +728,3 @@ GOACC_get_thread_num (void)
{
return 0;
}
-
-void
-GOACC_declare (int flags_m, size_t mapnum,
- void **hostaddrs, size_t *sizes, unsigned short *kinds)
-{
- int i;
-
- for (i = 0; i < mapnum; i++)
- {
- unsigned char kind = kinds[i] & 0xff;
-
- if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
- continue;
-
- switch (kind)
- {
- case GOMP_MAP_FORCE_ALLOC:
- case GOMP_MAP_FORCE_FROM:
- case GOMP_MAP_FORCE_TO:
- case GOMP_MAP_POINTER:
- case GOMP_MAP_RELEASE:
- case GOMP_MAP_DELETE:
- GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
- &kinds[i], GOMP_ASYNC_SYNC, 0);
- break;
-
- case GOMP_MAP_FORCE_DEVICEPTR:
- break;
-
- case GOMP_MAP_ALLOC:
- if (!acc_is_present (hostaddrs[i], sizes[i]))
- GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
- &kinds[i], GOMP_ASYNC_SYNC, 0);
- break;
-
- case GOMP_MAP_TO:
- GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
- &kinds[i], GOMP_ASYNC_SYNC, 0);
-
- break;
-
- case GOMP_MAP_FROM:
- GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
- &kinds[i], GOMP_ASYNC_SYNC, 0);
- break;
-
- case GOMP_MAP_FORCE_PRESENT:
- if (!acc_is_present (hostaddrs[i], sizes[i]))
- gomp_fatal ("[%p,%ld] is not mapped", hostaddrs[i],
- (unsigned long) sizes[i]);
- break;
-
- default:
- assert (0);
- break;
- }
- }
-}
diff --git a/libgomp/testsuite/libgomp.fortran/pr100981-2.f90 b/libgomp/testsuite/libgomp.fortran/pr100981-2.f90
index 12836d4..9814224 100644
--- a/libgomp/testsuite/libgomp.fortran/pr100981-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr100981-2.f90
@@ -9,6 +9,8 @@ complex function cdcdot(n, cx)
double precision :: dsdotr, dsdoti, dt1, dt3
kx = 1
+ dsdotr = 0
+ dsdoti = 0
do i = 1, n
dt1 = real(cx(kx))
dt3 = aimag(cx(kx))