aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-09-27 13:40:33 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-09-27 13:40:33 +0200
commit76425e19243cc310566fe7fd2f772039f9b8ec9f (patch)
tree96c1066811af285f2e0d4c8bf68351f7c0442280 /gcc
parentcecd314884a285957a110560bbd141a5f39ad7d3 (diff)
parent614e5696d730a65998ff5b0373f905795a758dd6 (diff)
downloadgcc-76425e19243cc310566fe7fd2f772039f9b8ec9f.zip
gcc-76425e19243cc310566fe7fd2f772039f9b8ec9f.tar.gz
gcc-76425e19243cc310566fe7fd2f772039f9b8ec9f.tar.bz2
Merge remote-tracking branch 'mainline/master' into ibuclaw/merge_mainline
Fixes: #1544
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog123
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog111
-rw-r--r--gcc/ada/adaint.c13
-rw-r--r--gcc/ada/bindgen.adb9
-rw-r--r--gcc/ada/cal.c2
-rw-r--r--gcc/ada/contracts.adb2
-rw-r--r--gcc/ada/cstreams.c8
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst8
-rw-r--r--gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst30
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst1120
-rw-r--r--gcc/ada/expect.c8
-rw-r--r--gcc/ada/gnat_rm.texi22
-rw-r--r--gcc/ada/gnat_ugn.texi12
-rw-r--r--gcc/ada/gsocket.h6
-rw-r--r--gcc/ada/mingw32.h28
-rw-r--r--gcc/ada/rtsfind.ads111
-rw-r--r--gcc/ada/s-oscons-tmplt.c3
-rw-r--r--gcc/ada/sem_ch12.adb7
-rw-r--r--gcc/ada/sem_ch5.adb8
-rw-r--r--gcc/ada/sem_util.adb24
-rw-r--r--gcc/ada/sem_warn.ads9
-rw-r--r--gcc/ada/sysdep.c6
-rw-r--r--gcc/builtins.def5
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.cc37
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c-cppbuiltin.cc11
-rw-r--r--gcc/c-family/c-lex.cc20
-rw-r--r--gcc/c-family/c-omp.cc42
-rw-r--r--gcc/c-family/c-pragma.cc5
-rw-r--r--gcc/c-family/c-pragma.h5
-rw-r--r--gcc/c/ChangeLog7
-rw-r--r--gcc/c/c-decl.cc4
-rw-r--r--gcc/c/c-lang.h3
-rw-r--r--gcc/c/c-parser.cc308
-rw-r--r--gcc/cfgcleanup.cc2
-rw-r--r--gcc/cfgcleanup.h1
-rw-r--r--gcc/cfgrtl.cc30
-rw-r--r--gcc/config.gcc22
-rw-r--r--gcc/config/aarch64/aarch64-arches.def3
-rw-r--r--gcc/config/aarch64/aarch64.h18
-rw-r--r--gcc/config/i386/avx512fp16intrin.h11
-rw-r--r--gcc/config/i386/i386-builtins.cc15
-rw-r--r--gcc/config/i386/i386-expand.cc116
-rw-r--r--gcc/config/i386/i386.cc5
-rw-r--r--gcc/config/ia64/ia64.cc24
-rwxr-xr-xgcc/config/nvptx/gen-multilib-matches.sh60
-rw-r--r--gcc/config/nvptx/nvptx.cc4
-rw-r--r--gcc/config/nvptx/nvptx.h8
-rw-r--r--gcc/config/nvptx/nvptx.opt2
-rw-r--r--gcc/config/nvptx/t-nvptx31
-rw-r--r--gcc/config/rs6000/rs6000-builtin.cc17
-rw-r--r--gcc/config/rs6000/rs6000-c.cc1
-rw-r--r--gcc/config/rs6000/rs6000-logue.cc2
-rw-r--r--gcc/config/rs6000/rs6000.cc6
-rw-r--r--gcc/config/rs6000/vector.md2
-rw-r--r--gcc/config/s390/s390.cc15
-rw-r--r--gcc/cp/ChangeLog25
-rw-r--r--gcc/cp/call.cc153
-rw-r--r--gcc/cp/cp-tree.h23
-rw-r--r--gcc/cp/decl.cc26
-rw-r--r--gcc/cp/error.cc8
-rw-r--r--gcc/cp/lambda.cc89
-rw-r--r--gcc/cp/mangle.cc67
-rw-r--r--gcc/cp/method.cc23
-rw-r--r--gcc/cp/module.cc17
-rw-r--r--gcc/cp/parser.cc471
-rw-r--r--gcc/cp/pt.cc3
-rw-r--r--gcc/cp/semantics.cc7
-rw-r--r--gcc/cp/typeck.cc172
-rw-r--r--gcc/cp/typeck2.cc34
-rw-r--r--gcc/d/decl.cc2
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/aggregate.d13
-rw-r--r--gcc/d/dmd/aggregate.h2
-rw-r--r--gcc/d/dmd/apply.d25
-rw-r--r--gcc/d/dmd/arrayop.d12
-rw-r--r--gcc/d/dmd/attrib.d4
-rw-r--r--gcc/d/dmd/canthrow.d6
-rw-r--r--gcc/d/dmd/chkformat.d600
-rw-r--r--gcc/d/dmd/clone.d6
-rw-r--r--gcc/d/dmd/cparse.d19
-rw-r--r--gcc/d/dmd/dcast.d4
-rw-r--r--gcc/d/dmd/declaration.h4
-rw-r--r--gcc/d/dmd/dimport.d7
-rw-r--r--gcc/d/dmd/dinterpret.d12
-rw-r--r--gcc/d/dmd/dmangle.d17
-rw-r--r--gcc/d/dmd/doc.d4
-rw-r--r--gcc/d/dmd/dsymbol.d6
-rw-r--r--gcc/d/dmd/dsymbol.h2
-rw-r--r--gcc/d/dmd/dsymbolsem.d48
-rw-r--r--gcc/d/dmd/dtemplate.d71
-rw-r--r--gcc/d/dmd/escape.d5
-rw-r--r--gcc/d/dmd/expression.d20
-rw-r--r--gcc/d/dmd/expression.h22
-rw-r--r--gcc/d/dmd/expressionsem.d92
-rw-r--r--gcc/d/dmd/func.d19
-rw-r--r--gcc/d/dmd/iasmgcc.d8
-rw-r--r--gcc/d/dmd/id.d2
-rw-r--r--gcc/d/dmd/init.d1
-rw-r--r--gcc/d/dmd/init.h1
-rw-r--r--gcc/d/dmd/initsem.d553
-rw-r--r--gcc/d/dmd/lexer.d9
-rw-r--r--gcc/d/dmd/module.h2
-rw-r--r--gcc/d/dmd/mtype.d649
-rw-r--r--gcc/d/dmd/mtype.h4
-rw-r--r--gcc/d/dmd/opover.d9
-rw-r--r--gcc/d/dmd/parse.d102
-rw-r--r--gcc/d/dmd/root/object.h2
-rw-r--r--gcc/d/dmd/semantic3.d40
-rw-r--r--gcc/d/dmd/transitivevisitor.d73
-rw-r--r--gcc/d/dmd/typesem.d18
-rw-r--r--gcc/d/expr.cc33
-rw-r--r--gcc/d/runtime.def5
-rw-r--r--gcc/doc/install.texi9
-rw-r--r--gcc/doc/invoke.texi9
-rw-r--r--gcc/doc/sourcebuild.texi2
-rw-r--r--gcc/fortran/ChangeLog66
-rw-r--r--gcc/fortran/trans-expr.cc83
-rw-r--r--gcc/fortran/trans.h3
-rw-r--r--gcc/omp-low.cc19
-rw-r--r--gcc/range-op.cc18
-rw-r--r--gcc/testsuite/ChangeLog119
-rw-r--r--gcc/testsuite/c-c++-common/goacc/reduction-7.c22
-rw-r--r--gcc/testsuite/c-c++-common/goacc/reduction-8.c12
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assume-1.c29
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assume-2.c46
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assume-3.c27
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assumes-1.c26
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assumes-2.c23
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assumes-3.c15
-rw-r--r--gcc/testsuite/c-c++-common/gomp/assumes-4.c6
-rw-r--r--gcc/testsuite/c-c++-common/gomp/begin-assumes-1.c46
-rw-r--r--gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c63
-rw-r--r--gcc/testsuite/c-c++-common/gomp/begin-assumes-3.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/begin-assumes-4.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/declare-target-6.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-lambda13.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating.h30
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating1.C447
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating10.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating2.C157
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating3.C134
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating4.C126
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating5.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating6.C30
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating7.C119
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating8.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp23/ext-floating9.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp23/static-operator-call1.C41
-rw-r--r--gcc/testsuite/g++.dg/cpp23/static-operator-call2.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp23/static-operator-call3.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/char8_t3.C37
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/char8_t4.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constinit3.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C4
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/char8_t-init-2.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/is_convertible3.C9
-rw-r--r--gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C9
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-1.C15
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-15.C41
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-16.C26
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-17.C17
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-2.C15
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-9.C20
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2.cc17
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2.h38
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_a.C39
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_b.C18
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_c.H5
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_d.C8
-rw-r--r--gcc/testsuite/g++.dg/other/mult-stor1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/crash39.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef8.C10
-rw-r--r--gcc/testsuite/g++.dg/template/error30.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr107029.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/operator.C2
-rw-r--r--gcc/testsuite/g++.target/i386/float16-1.C4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/popcount6.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107009.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-1.c70
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-2.c59
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-3.c69
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-4.c59
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr100645.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr96072.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/ret-1.c41
-rw-r--r--gcc/testsuite/gdc.test/compilable/commontype.d20
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/cimports2a.i4
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/cimports2b.i4
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/format23327.d7
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/format23327/write.d0
-rw-r--r--gcc/testsuite/gdc.test/compilable/segfaultgolf.d50
-rw-r--r--gcc/testsuite/gdc.test/compilable/statictemplatethis.d45
-rw-r--r--gcc/testsuite/gdc.test/compilable/test13123.d38
-rw-r--r--gcc/testsuite/gdc.test/compilable/test21243.d21
-rw-r--r--gcc/testsuite/gdc.test/compilable/test21956.d16
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22674.d10
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23173.d6
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23258.d21
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23306.d7
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23327.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/vararg.d20
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag10169.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag10783.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag13528.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag14145.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag15713.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag23355.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag3438.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag3438b.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag8894.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/dip22a.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/e15876_1.d15
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/e15876_3.d30
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/e15876_4.d26
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail10968.d31
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail121.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail13123.d21
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail17646.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18892.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18970.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18979.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19103.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19687.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19913.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail21243.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail23109.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7372.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/failoffset.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10938.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice12174.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice15855.d24
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice18469.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice19755.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/fail7372.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d1
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/mixinprop.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test15785.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test15897.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test16188.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test17380spec.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21096.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22680.d17
-rw-r--r--gcc/testsuite/gdc.test/runnable/newaa.d23
-rw-r--r--gcc/testsuite/gdc.test/runnable/test23234.d22
-rw-r--r--gcc/testsuite/gdc.test/runnable/testassign.d16
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_10.f9066
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_4.f9043
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_5.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_6.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_7.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_8.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_9.f9042
-rw-r--r--gcc/testsuite/gfortran.dg/intent_out_15.f9027
-rw-r--r--gcc/tree-core.h4
-rw-r--r--gcc/tree-ssa-dom.cc35
-rw-r--r--gcc/tree-ssa-reassoc.cc21
-rw-r--r--gcc/tree.cc1
-rw-r--r--gcc/tree.h4
-rw-r--r--gcc/value-range.cc22
-rw-r--r--gcc/value-range.h9
268 files changed, 6704 insertions, 3132 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4ff50c3..4bd177d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,126 @@
+2022-09-26 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Add missing dash for
+ Wanalyzer-exposure-through-uninit-copy.
+
+2022-09-26 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107009
+ * range-op.cc (operator_bitwise_and::op1_range): Optimize 0 = x & MASK.
+ (range_op_bitwise_and_tests): New test.
+
+2022-09-26 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107009
+ * tree-ssa-dom.cc
+ (dom_opt_dom_walker::set_global_ranges_from_unreachable_edges):
+ Iterate over exports.
+
+2022-09-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * config.gcc (with_arch) [nvptx]: Allow '--with-arch' to override
+ the default.
+ * config/nvptx/gen-multilib-matches.sh: New.
+ * config/nvptx/t-nvptx (MULTILIB_OPTIONS, MULTILIB_MATCHES)
+ (MULTILIB_EXCEPTIONS): Handle this.
+ * doc/install.texi (Specific) <nvptx-*-none>: Document this.
+ * doc/invoke.texi (Nvidia PTX Options): Likewise.
+
+2022-09-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * config.gcc (TM_MULTILIB_CONFIG) [nvptx]: Set to '$with_arch'.
+ * config/nvptx/t-nvptx (MULTILIB_OPTIONS, MULTILIB_MATCHES)
+ (MULTILIB_EXCEPTIONS): Handle it.
+
+2022-09-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * config.gcc (with_arch) [nvptx]: Set to 'sm_30'.
+ * config/nvptx/nvptx.cc (nvptx_option_override): Assert that
+ '-misa' appeared.
+ * config/nvptx/nvptx.h (OPTION_DEFAULT_SPECS): Define.
+ * config/nvptx/nvptx.opt (misa=): Remove 'Init'.
+
+2022-09-26 Thomas Schwinge <thomas@codesourcery.com>
+
+ * config/nvptx/nvptx.h (ASM_SPEC): Define.
+
+2022-09-26 Jeff Law <jeffreyalaw@gmail.com>
+
+ * cfgcleanup.cc (bb_is_just_return): No longer static.
+ * cfgcleanup.h (bb_is_just_return): Add prototype.
+ * cfgrtl.cc (fixup_reorder_chain): Do not create an
+ unconditional jump to a return block. Conditionally
+ remove unreachable blocks.
+
+2022-09-26 Tobias Burnus <tobias@codesourcery.com>
+
+ PR middle-end/106982
+ * omp-low.cc (lower_oacc_reductions): Add some unshare_expr.
+
+2022-09-26 Martin Liska <mliska@suse.cz>
+
+ * config/s390/s390.cc (s390_rtx_costs): Remove dest variable
+ and use only dst.
+
+2022-09-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-arches.def (armv9.1-a): Define.
+ (armv9.2-a): Likewise.
+ (armv9.3-a): Likewise.
+ * config/aarch64/aarch64.h (AARCH64_FL_V9_1): Likewise.
+ (AARCH64_FL_V9_2): Likewise.
+ (AARCH64_FL_V9_3): Likewise.
+ (AARCH64_FL_FOR_ARCH9_1): Likewise.
+ (AARCH64_FL_FOR_ARCH9_2): Likewise.
+ (AARCH64_FL_FOR_ARCH9_3): Likewise.
+ (AARCH64_ISA_V9_1): Likewise.
+ (AARCH64_ISA_V9_2): Likewise.
+ (AARCH64_ISA_V9_3): Likewise.
+ * doc/invoke.texi (AArch64 Options): Document armv9.1-a, armv9.2-a,
+ armv9.3-a values to -march.
+
+2022-09-26 Martin Liska <mliska@suse.cz>
+
+ * value-range.cc (tree_compare): Remove unused function.
+
+2022-09-26 Kewen Lin <linkw@linux.ibm.com>
+
+ PR target/96072
+ * config/rs6000/rs6000-logue.cc (rs6000_emit_epilogue): Update the
+ condition for adding REG_CFA_DEF_CFA reg note with
+ frame_pointer_needed_indeed.
+
+2022-09-26 Kewen Lin <linkw@linux.ibm.com>
+
+ PR target/100645
+ * config/rs6000/vector.md (vec_shr_<mode>): Replace condition
+ TARGET_ALTIVEC with VECTOR_UNIT_ALTIVEC_OR_VSX_P.
+
+2022-09-26 Hongtao Liu <hongtao.liu@intel.com>
+ Liwei Xu <liwei.xu@intel.com>
+
+ PR target/53346
+ * config/i386/i386-expand.cc (expand_vec_perm_shufps_shufps):
+ New function.
+ (ix86_expand_vec_perm_const_1): Insert
+ expand_vec_perm_shufps_shufps at the end of 2-instruction
+ expand sequence.
+
+2022-09-25 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+
+ * doc/sourcebuild.texi: Fix chapter level.
+
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107001
+ * omp-low.cc (lower_omp_taskgroup): Don't add GOMP_RETURN statement
+ at the end.
+ * omp-expand.cc (build_omp_regions_1): Clarify GF_OMP_TARGET_KIND_DATA
+ is not stand-alone directive. For GIMPLE_OMP_TASKGROUP, also don't
+ update parent.
+ (omp_make_gimple_edges) <case GIMPLE_OMP_TASKGROUP>: Reset
+ cur_region back after new_omp_region.
+
2022-09-23 Vineet Gupta <vineetg@rivosinc.com>
* config/riscv/riscv.h (LOCAL_SYM_P): New.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index c0c32de..38c805d 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220924
+20220927
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index fe048b8..db4ac0d 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,102 @@
+2022-09-26 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst: Rename Valid_Image.
+ * gnat_rm.texi: Regenerate.
+ * gnat_ugn.texi: Regenerate.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Build_Instance_Compilation_Unit_Nodes): Relocate
+ auxiliary declarations from the original compilation unit to the
+ newly created compilation unit for the spec.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * rtsfind.ads
+ (RTU_Id): Remove unreferenced packages; fix whitespace.
+ (RE_Id): Remove unreferenced entities; add comment about entity
+ that is only used by GNATprove and not by GNAT.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * s-oscons-tmplt.c (STR, STR1): Remove.
+
+2022-09-26 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst
+ (-gnateT): Document new parameter Long_Long_Long_Size.
+ * gnat_ugn.texi: Regenerate.
+
+2022-09-26 Steve Baird <baird@adacore.com>
+
+ * bindgen.adb: When the binder is invoked for the device, specify
+ the CUDA_Global aspect for the adainit and adafinal procedures via
+ a pragma instead of via an aspect_specification.
+
+2022-09-26 Kévin Le Gouguec <legouguec@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst
+ (Linker Switches): Document support for mold along with gold; add some
+ advice regarding OpenSSL in the Pro version.
+ * gnat_ugn.texi: Regenerate.
+
+2022-09-26 Tucker Taft <taft@adacore.com>
+
+ * sem_util.adb (Original_Aspect_Pragma_Name): Check for Check
+ pragmas.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch5.adb (Analyze_Iterator_Specification): Delay expansion
+ based on Full_Analysis flag.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch5.adb (Analyze_Iterator_Specification): Delay expansion of
+ for iterated component association just like it is done within
+ quantified expression.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * contracts.adb (Analyze_Object_Contract): Check SPARK_Mode before
+ applying SPARK rule.
+
+2022-09-26 Justin Squirek <squirek@adacore.com>
+
+ * sem_util.adb
+ (Accessibility_Level): Modify indexed and selected components case
+ by reducing the scope where Original_Node gets used.
+
+2022-09-26 Boris Yakobowski <yakobowski@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Remove documentation for
+ gnatmetric.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * gsocket.h: Remove redefinition of _WIN32_WINNT.
+ * mingw32.h: Remove conditional definition of _WIN32_WINNT.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * mingw32.h: Remove condition definition of MAXPATHLEN; the include
+ directive for stdlib.h was most likely intended to provide the
+ MAX_PATH.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * adaint.c: Remove conditional #include directives for old MinGW.
+ * cal.c: Always include winsock.h, since it is part of modern
+ MinGW.
+ * cstreams.c: Remove workaround for old MinGW.
+ * expect.c: Remove conditional #include directive for old MinGW.
+ * mingw32.h: Remove STD_MINGW and OLD_MINGW declarations.
+ * sysdep.c: Remove conditional #include directive for old MinGW.
+
+2022-09-26 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_warn.ads (Has_Junk_Name): Reword comment.
+
2022-09-20 Martin Liska <mliska@suse.cz>
* exp_ch6.adb: Replace "the the" with "the".
@@ -66,7 +165,7 @@
2022-09-12 Eric Botcazou <ebotcazou@adacore.com>
- * contracts.adb (uild_Subprogram_Contract_Wrapper): Remove useless
+ * contracts.adb (Build_Subprogram_Contract_Wrapper): Remove useless
local variable. In the case of a function, replace the extended
return statement by a block statement declaring a renaming of the
call to the local subprogram after removing side effects manually.
@@ -1179,14 +1278,14 @@
2022-09-02 Eric Botcazou <ebotcazou@adacore.com>
- * exp_util.adb (Expand_Subtype_From_Expr): Be prepared for
- rewritten aggregates as expressions.
+ * exp_util.adb (Expand_Subtype_From_Expr): Be prepared for rewritten
+ aggregates as expressions.
2022-09-02 Gary Dismukes <dismukes@adacore.com>
- * exp_ch6.adb (Expand_Simple_Function_Return) Bypass creation of an actual
- subtype and unchecked conversion to that subtype when the underlying type
- of the expression has discriminants without defaults.
+ * exp_ch6.adb (Expand_Simple_Function_Return) Bypass creation of an
+ actual subtype and unchecked conversion to that subtype when the
+ underlying type of the expression has discriminants without defaults.
2022-09-02 Eric Botcazou <ebotcazou@adacore.com>
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 2ae4ded..199dbe0 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -200,11 +200,7 @@ UINT __gnat_current_ccs_encoding;
#endif
/* wait.h processing */
-#ifdef __MINGW32__
-# if OLD_MINGW
-# include <sys/wait.h>
-# endif
-#elif defined (__vxworks) && defined (__RTP__)
+#if defined (__vxworks) && defined (__RTP__)
# include <wait.h>
#elif defined (__Lynx__)
/* ??? We really need wait.h and it includes resource.h on Lynx. GCC
@@ -214,7 +210,7 @@ UINT __gnat_current_ccs_encoding;
preventing the inclusion of the GCC header from doing anything. */
# define GCC_RESOURCE_H
# include <sys/wait.h>
-#elif defined (__PikeOS__)
+#elif defined (__PikeOS__) || defined (__MINGW32__)
/* No wait() or waitpid() calls available. */
#else
/* Default case. */
@@ -335,11 +331,6 @@ const char *__gnat_library_template = GNAT_LIBRARY_TEMPLATE;
#if defined (__MINGW32__)
#include "mingw32.h"
-
-#if OLD_MINGW
-#include <sys/param.h>
-#endif
-
#else
#include <sys/param.h>
#endif
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index b2fa44d..f2aaa2d 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -134,9 +134,6 @@ package body Bindgen is
-- Text for aspect specifications (if any) given as part of the
-- Adainit and Adafinal spec declarations.
- function Aspect_Text return String is
- (if Enable_CUDA_Device_Expansion then " with CUDA_Global" else "");
-
----------------------------------
-- Interface_State Pragma Table --
----------------------------------
@@ -2644,10 +2641,11 @@ package body Bindgen is
end if;
WBI ("");
- WBI (" procedure " & Ada_Init_Name.all & Aspect_Text & ";");
+ WBI (" procedure " & Ada_Init_Name.all & ";");
if Enable_CUDA_Device_Expansion then
WBI (" pragma Export (C, " & Ada_Init_Name.all &
", Link_Name => """ & Device_Ada_Init_Link_Name & """);");
+ WBI (" pragma CUDA_Global (" & Ada_Init_Name.all & ");");
else
WBI (" pragma Export (C, " & Ada_Init_Name.all & ", """ &
Ada_Init_Name.all & """);");
@@ -2662,11 +2660,12 @@ package body Bindgen is
if not Cumulative_Restrictions.Set (No_Finalization) then
WBI ("");
- WBI (" procedure " & Ada_Final_Name.all & Aspect_Text & ";");
+ WBI (" procedure " & Ada_Final_Name.all & ";");
if Enable_CUDA_Device_Expansion then
WBI (" pragma Export (C, " & Ada_Final_Name.all &
", Link_Name => """ & Device_Ada_Final_Link_Name & """);");
+ WBI (" pragma CUDA_Global (" & Ada_Final_Name.all & ");");
else
WBI (" pragma Export (C, " & Ada_Final_Name.all & ", """ &
Ada_Final_Name.all & """);");
diff --git a/gcc/ada/cal.c b/gcc/ada/cal.c
index e1ab692..09bcc15 100644
--- a/gcc/ada/cal.c
+++ b/gcc/ada/cal.c
@@ -53,10 +53,8 @@
#ifdef __MINGW32__
#include "mingw32.h"
-#if STD_MINGW
#include <winsock.h>
#endif
-#endif
void
__gnat_timeval_to_duration (struct timeval *t, long long *sec, long *usec)
diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index 34db67a..dd573d3 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -1207,7 +1207,7 @@ package body Contracts is
-- A Ghost object cannot be effectively volatile (SPARK RM 6.9(7) and
-- SPARK RM 6.9(19)).
- elsif Is_Effectively_Volatile (Obj_Id) then
+ elsif SPARK_Mode = On and then Is_Effectively_Volatile (Obj_Id) then
Error_Msg_N ("ghost object & cannot be volatile", Obj_Id);
-- A Ghost object cannot be imported or exported (SPARK RM 6.9(7)).
diff --git a/gcc/ada/cstreams.c b/gcc/ada/cstreams.c
index 10cc3a6..fc583e1 100644
--- a/gcc/ada/cstreams.c
+++ b/gcc/ada/cstreams.c
@@ -97,14 +97,6 @@ extern "C" {
#undef fileno
#endif
-/* The _IONBF value in MINGW32 stdio.h is wrong. */
-#if defined (WINNT) || defined (_WINNT)
-#if OLD_MINGW
-#undef _IONBF
-#define _IONBF 0004
-#endif
-#endif
-
int
__gnat_feof (FILE *stream)
{
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index c25e3d4..d839b1f 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -1623,13 +1623,13 @@ Multi-dimensional arrays can be modified, as shown by this example:
which changes element (1,2) to 20 and (3,4) to 30.
-Attribute Valid_Image
+Attribute Valid_Value
=======================
-.. index:: Valid_Image
+.. index:: Valid_Value
-The ``'Valid_Image`` attribute is defined for enumeration types other than
+The ``'Valid_Value`` attribute is defined for enumeration types other than
those in package Standard. This attribute is a function that takes
-a String, and returns Boolean. ``T'Valid_Image (S)`` returns True
+a String, and returns Boolean. ``T'Valid_Value (S)`` returns True
if and only if ``T'Value (S)`` would not raise Constraint_Error.
Attribute Valid_Scalars
diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
index 6a47809..d4bddff 100644
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -1719,6 +1719,7 @@ Alphabetical List of All Switches
Float_Words_BE : Nat; -- Float words stored big-endian?
Int_Size : Pos; -- Standard.Integer'Size
Long_Double_Size : Pos; -- Standard.Long_Long_Float'Size
+ Long_Long_Long_Size : Pos; -- Standard.Long_Long_Long_Integer'Size
Long_Long_Size : Pos; -- Standard.Long_Long_Integer'Size
Long_Size : Pos; -- Standard.Long_Integer'Size
Maximum_Alignment : Pos; -- Maximum permitted alignment
@@ -1816,6 +1817,7 @@ Alphabetical List of All Switches
Float_Words_BE 0
Int_Size 64
Long_Double_Size 128
+ Long_Long_Long_Size 128
Long_Long_Size 64
Long_Size 64
Maximum_Alignment 16
@@ -6229,11 +6231,33 @@ Linker switches can be specified after :switch:`-largs` builder switch.
.. index:: -fuse-ld=name
:switch:`-fuse-ld={name}`
- Linker to be used. The default is ``bfd`` for :file:`ld.bfd`,
- the alternative being ``gold`` for :file:`ld.gold`. The later is
- a more recent and faster linker, but only available on GNU/Linux
+ Linker to be used. The default is ``bfd`` for :file:`ld.bfd`; ``gold``
+ (for :file:`ld.gold`) and ``mold`` (for :file:`ld.mold`) are more
+ recent and faster alternatives, but only available on GNU/Linux
platforms.
+ .. only:: PRO
+
+ The GNAT distribution for native Linux platforms includes ``mold``,
+ compiled against OpenSSL version 1.1; however, the distribution does
+ not include OpenSSL. In order to use this linker, you may either:
+
+ * use your system's OpenSSL library, if the version matches: in this
+ situation, you need not do anything beside using the
+ :switch:`-fuse-ld=mold` switch,
+
+ * obtain a source distribution for OpenSSL 1.1, compile the
+ :file:`libcrypto.so` library and install it in the directory of
+ your choice, then include this directory in the
+ :envvar:`LD_LIBRARY_PATH` environment variable,
+
+ * install another copy of ``mold`` by other means in the directory
+ of your choice, and include this directory in the :envvar:`PATH`
+ environment variable; you may find this alternative preferable if
+ the copy of ``mold`` included in GNAT does not suit your needs
+ (e.g. being able to link against your system's OpenSSL, or using
+ another version of ``mold``).
+
.. _Binding_with_gnatbind:
Binding with ``gnatbind``
diff --git a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
index d670839..92877a2 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
@@ -15,7 +15,6 @@ This chapter describes a number of utility programs:
* :ref:`The_File_Cleanup_Utility_gnatclean`
* :ref:`The_GNAT_Library_Browser_gnatls`
* :ref:`The_Coding_Standard_Verifier_gnatcheck`
- * :ref:`The_GNAT_Metrics_Tool_gnatmetric`
* :ref:`The_GNAT_Pretty_Printer_gnatpp`
* :ref:`The_Body_Stub_Generator_gnatstub`
* :ref:`The_Backtrace_Symbolizer_gnatsymbolize`
@@ -487,1123 +486,6 @@ building specialized scripts.
For full details, plese refer to :title:`GNATcheck Reference Manual`.
-
-.. only:: PRO or GPL
-
- .. _The_GNAT_Metrics_Tool_gnatmetric:
-
- The GNAT Metrics Tool ``gnatmetric``
- ====================================
-
- .. index:: ! gnatmetric
- .. index:: Metric tool
-
- The ``gnatmetric`` tool is a utility
- for computing various program metrics.
- It takes an Ada source file as input and generates a file containing the
- metrics data as output. Various switches control which
- metrics are reported.
-
- ``gnatmetric`` is a project-aware tool
- (see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
- ``gnatmetric`` switches is named ``Metrics``.
-
- The ``gnatmetric`` command has the form
-
- ::
-
- $ gnatmetric [ switches ] { filename }
-
- where:
-
- * ``switches`` specify the metrics to compute and define the destination for
- the output
-
- * Each ``filename`` is the name of a source file to process. 'Wildcards' are
- allowed, and the file name may contain path information. If no
- ``filename`` is supplied, then the ``switches`` list must contain at least
- one :switch:`--files` switch (see :ref:`Other_gnatmetric_Switches`).
- Including both a :switch:`--files` switch and one or more ``filename``
- arguments is permitted.
-
- Note that it is no longer necessary to specify the Ada language version;
- ``gnatmetric`` can process Ada source code written in any version from
- Ada 83 onward without specifying any language version switch.
-
- The following subsections describe the various switches accepted by
- ``gnatmetric``, organized by category.
-
- .. _Output_File_Control-gnatmetric:
-
- Output File Control
- -------------------
-
- .. index:: Output file control in gnatmetric
-
- ``gnatmetric`` has two output formats. It can generate a
- textual (human-readable) form, and also XML. By default only textual
- output is generated.
-
- When generating the output in textual form, ``gnatmetric`` creates
- for each Ada source file a corresponding text file
- containing the computed metrics, except for the case when the set of metrics
- specified by gnatmetric parameters consists only of metrics that are computed
- for the whole set of analyzed sources, but not for each Ada source.
- By default, the name of the file containing metric information for a source
- is obtained by appending the :file:`.metrix` suffix to the
- name of the input source file. If not otherwise specified and no project file
- is specified as ``gnatmetric`` option this file is placed in the same
- directory as where the source file is located. If ``gnatmetric`` has a
- project file as its parameter, it places all the generated files in the
- object directory of the project (or in the project source directory if the
- project does not define an object directory). If :switch:`--subdirs` option
- is specified, the files are placed in the subrirectory of this directory
- specified by this option.
-
- All the output information generated in XML format is placed in a single
- file. By default the name of this file is :file:`metrix.xml`.
- If not otherwise specified and if no project file is specified
- as ``gnatmetric`` option this file is placed in the
- current directory.
-
- Some of the computed metrics are summed over the units passed to
- ``gnatmetric``; for example, the total number of lines of code.
- By default this information is sent to :file:`stdout`, but a file
- can be specified with the :switch:`--global-file-name` switch.
-
- The following switches control the ``gnatmetric`` output:
-
- .. index:: --generate-xml-output (gnatmetric)
-
- :switch:`--generate-xml-output`
- Generate XML output.
-
- .. index:: --generate-xml-schema (gnatmetric)
-
- :switch:`--generate-xml-schema`
- Generate XML output and an XML schema file that describes the structure
- of the XML metric report. This schema is assigned to the XML file. The schema
- file has the same name as the XML output file with :file:`.xml` suffix replaced
- with :file:`.xsd`.
-
- .. index:: --no-text-output (gnatmetric)
-
-
- :switch:`--no-text-output`
- Do not generate the output in text form (implies :switch:`-x`).
-
- .. index:: --output-dir (gnatmetric)
-
-
- :switch:`--output-dir={output_dir}`
- Put text files with detailed metrics into ``output_dir``.
-
- .. index:: --output-suffix (gnatmetric)
-
-
- :switch:`--output-suffix={file_suffix}`
- Use ``file_suffix``, instead of :file:`.metrix`
- in the name of the output file.
-
- .. index:: --global-file-name (gnatmetric)
-
- :switch:`--global-file-name={file_name}`
- Put global metrics into ``file_name``.
-
- .. index:: --xml-file-name (gnatmetric)
-
-
- :switch:`--xml-file-name={file_name}`
- Put the XML output into ``file_name``
- (also implies :switch:`--generate-xml-output`).
-
- .. index:: --short-file-names (gnatmetric)
-
- :switch:`--short-file-names`
- Use 'short' source file names in the output. (The ``gnatmetric``
- output includes the name(s) of the Ada source file(s) from which the
- metrics are computed. By default each name includes the absolute
- path. The :switch:`--short-file-names` switch causes ``gnatmetric``
- to exclude all directory information from the file names that are
- output.)
-
- .. index:: --wide-character-encoding (gnatmetric)
-
- :switch:`--wide-character-encoding={e}`
- Specify the wide character encoding method for the input and output
- files. ``e`` is one of the following:
-
- * *8* - UTF-8 encoding
-
- * *b* - Brackets encoding (default value)
-
-
- .. index:: Disable Metrics For Local Units in gnatmetric
-
- .. _Disable_Metrics_For_Local_Units:
-
- Disable Metrics For Local Units
- -------------------------------
-
- ``gnatmetric`` relies on the GNAT compilation model --
- one compilation
- unit per one source file. It computes line metrics for the whole source
- file, and it also computes syntax
- and complexity metrics for the file's outermost unit.
-
- By default, ``gnatmetric`` will also compute all metrics for certain
- kinds of locally declared program units:
-
- * subprogram (and generic subprogram) bodies;
-
- * package (and generic package) specs and bodies;
-
- * task object and type specifications and bodies;
-
- * protected object and type specifications and bodies.
-
- .. index:: Eligible local unit (for gnatmetric)
-
- These kinds of entities will be referred to as
- *eligible local program units*, or simply *eligible local units*,
- in the discussion below.
-
- Note that a subprogram declaration, generic instantiation,
- or renaming declaration only receives metrics
- computation when it appear as the outermost entity
- in a source file.
-
- Suppression of metrics computation for eligible local units can be
- obtained via the following switch:
-
-
- .. index:: --no-local-metrics (gnatmetric)
-
-
- :switch:`--no-local-metrics`
- Do not compute detailed metrics for eligible local program units.
-
-
- .. _Specifying_a_set_of_metrics_to_compute:
-
- Specifying a set of metrics to compute
- --------------------------------------
-
- By default all the metrics are reported. The switches described in this
- subsection allow you to control, on an individual basis, whether metrics are
- reported. If at least one positive metric switch is specified (that is, a
- switch that defines that a given metric or set of metrics is to be computed),
- then only explicitly specified metrics are reported.
-
- .. _Line_Metrics_Control:
-
- Line Metrics Control
- ^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Line metrics control in gnatmetric
-
- For each source file, and for each of its eligible local program
- units, ``gnatmetric`` computes the following metrics:
-
- * the total number of lines;
-
- * the total number of code lines (i.e., non-blank lines that are not
- comments)
-
- * the number of comment lines
-
- * the number of code lines containing end-of-line comments;
-
- * the comment percentage: the ratio between the number of lines that
- contain comments and the number of all non-blank lines, expressed as
- a percentage
-
- * the number of empty lines and lines containing only space characters
- and/or format effectors (blank lines)
-
- * the average number of code lines in subprogram bodies, task bodies,
- entry bodies and statement sequences in package bodies
-
- ``gnatmetric`` sums the values of the line metrics for all the files
- being processed and then generates the cumulative results. The tool
- also computes for all the files being processed the average number of
- code lines in bodies.
-
- You can use the following switches to select the specific line metrics
- to be reported.
-
-
- .. index:: --lines (gnatmetric)
- .. index:: --no-lines (gnatmetric)
-
-
- :switch:`--lines-all`
- Report all the line metrics
-
-
- :switch:`--no-lines-all`
- Do not report any of line metrics
-
-
- :switch:`--lines`
- Report the number of all lines
-
-
- :switch:`--no-lines`
- Do not report the number of all lines
-
-
- :switch:`--lines-code`
- Report the number of code lines
-
-
- :switch:`--no-lines-code`
- Do not report the number of code lines
-
-
- :switch:`--lines-comment`
- Report the number of comment lines
-
-
- :switch:`--no-lines-comment`
- Do not report the number of comment lines
-
-
- :switch:`--lines-eol-comment`
- Report the number of code lines containing
- end-of-line comments
-
-
- :switch:`--no-lines-eol-comment`
- Do not report the number of code lines containing
- end-of-line comments
-
-
- :switch:`--lines-ratio`
- Report the comment percentage in the program text
-
-
- :switch:`--no-lines-ratio`
- Do not report the comment percentage in the program text
-
-
- :switch:`--lines-blank`
- Report the number of blank lines
-
-
- :switch:`--no-lines-blank`
- Do not report the number of blank lines
-
-
- :switch:`--lines-average`
- Report the average number of code lines in subprogram bodies, task bodies,
- entry bodies and statement sequences in package bodies.
-
-
- :switch:`--no-lines-average`
- Do not report the average number of code lines in subprogram bodies,
- task bodies, entry bodies and statement sequences in package bodies.
-
-
- :switch:`--lines-spark`
- Report the number of lines written in SPARK.
-
-
- :switch:`--no-lines-spark`
- Do not report the number of lines written in SPARK.
-
-
- .. _Syntax_Metrics_Control:
-
- Syntax Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Syntax metrics control in gnatmetric
-
- ``gnatmetric`` computes various syntactic metrics for the
- outermost unit and for each eligible local unit:
-
- * *LSLOC ('Logical Source Lines Of Code')*
- The total number of declarations and the total number of
- statements. Note that the definition of declarations is the one
- given in the reference manual:
-
- "Each of the following is defined to be a declaration: any
- basic_declaration; an enumeration_literal_specification; a
- discriminant_specification; a component_declaration; a
- loop_parameter_specification; a parameter_specification; a
- subprogram_body; an entry_declaration; an
- entry_index_specification; a choice_parameter_specification; a
- generic_formal_parameter_declaration."
-
- This means for example that each enumeration literal adds one to
- the count, as well as each subprogram parameter.
-
- * *Maximal static nesting level of inner program units*
- According to :title:`Ada Reference Manual`, 10.1(1):
-
- "A program unit is either a package, a task unit, a protected
- unit, a protected entry, a generic unit, or an explicitly
- declared subprogram other than an enumeration literal."
-
- * *Maximal nesting level of composite syntactic constructs*
- This corresponds to the notion of the maximum nesting level in the
- GNAT built-in style checks (see :ref:`Style_Checking`).
-
- * *Number of formal parameters*
- Number of formal parameters of a subprogram; if a subprogram does
- have parameters, then numbers of "in", "out" and "in out"
- parameters are also reported. This metric is reported for
- subprogram specifications and for subprogram instantiations. For
- subprogram bodies, expression functions and null procedures this
- metric is reported if the construct acts as a subprogram
- declaration but is not a completion of previous declaration. This
- metric is not reported for generic and formal subprograms.
-
- For the outermost unit in the file, ``gnatmetric`` additionally
- computes the following metrics:
-
- * *Public subprograms*
- This metric is computed for package specs. It is the number of
- subprograms and generic subprograms declared in the visible part
- (including the visible part of nested packages, protected objects,
- and protected types).
-
-
- * *All subprograms*
- This metric is computed for bodies and subunits. The metric is
- equal to a total number of subprogram bodies in the compilation
- unit.
- Neither generic instantiations nor renamings-as-a-body nor body
- stubs are counted. Any subprogram body is counted, independently
- of its nesting level and enclosing constructs. Generic bodies and
- bodies of protected subprograms are counted in the same way as
- 'usual' subprogram bodies.
-
-
- * *Public types*
- This metric is computed for package specs and generic package
- declarations. It is the total number of types that can be
- referenced from outside this compilation unit, plus the number of
- types from all the visible parts of all the visible generic
- packages. Generic formal types are not counted. Only types, not
- subtypes, are included.
-
- Along with the total number of public types, the following
- types are counted and reported separately:
-
- * *Abstract types*
-
- * *Root tagged types^ (abstract, non-abstract, private,
- non-private). Type extensions are *not* counted
-
- * *Private types* (including private extensions)
-
- * *Task types*
-
- * *Protected types*
-
- * *All types*
- This metric is computed for any compilation unit. It is equal to
- the total number of the declarations of different types given in
- the compilation unit. The private and the corresponding full type
- declaration are counted as one type declaration. Incomplete type
- declarations and generic formal types are not counted.
- No distinction is made among different kinds of types (abstract,
- private etc.); the total number of types is reported.
-
- By default, all the syntax metrics are reported. You can use the following
- switches to select specific syntax metrics.
-
-
- .. index:: --syntax (gnatmetric)
- .. index:: --no-syntax (gnatmetric)
-
-
- :switch:`--syntax-all`
- Report all the syntax metrics
-
-
- :switch:`--no-syntax-all`
- Do not report any of syntax metrics
-
-
- :switch:`--declarations`
- Report the total number of declarations
-
-
- :switch:`--no-declarations`
- Do not report the total number of declarations
-
-
- :switch:`--statements`
- Report the total number of statements
-
-
- :switch:`--no-statements`
- Do not report the total number of statements
-
-
- :switch:`--public-subprograms`
- Report the number of public subprograms in a compilation unit
-
-
- :switch:`--no-public-subprograms`
- Do not report the number of public subprograms in a compilation unit
-
-
- :switch:`--all-subprograms`
- Report the number of all the subprograms in a compilation unit
-
-
- :switch:`--no-all-subprograms`
- Do not report the number of all the subprograms in a compilation unit
-
-
- :switch:`--public-types`
- Report the number of public types in a compilation unit
-
-
- :switch:`--no-public-types`
- Do not report the number of public types in a compilation unit
-
-
- :switch:`--all-types`
- Report the number of all the types in a compilation unit
-
-
- :switch:`--no-all-types`
- Do not report the number of all the types in a compilation unit
-
-
- :switch:`--unit-nesting`
- Report the maximal program unit nesting level
-
-
- :switch:`--no-unit-nesting`
- Do not report the maximal program unit nesting level
-
-
- :switch:`--construct-nesting`
- Report the maximal construct nesting level
-
-
- :switch:`--no-construct-nesting`
- Do not report the maximal construct nesting level
-
- :switch:`--param-number`
- Report the number of subprogram parameters
-
-
- :switch:`--no-param-number`
- Do not report the number of subprogram parameters
-
-
- .. _Contract_Metrics_Control:
-
- Contract Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Contract metrics control in gnatmetric
-
- :switch:`--contract-all`
- Report all the contract metrics
-
-
- :switch:`--no-contract-all`
- Do not report any of the contract metrics
-
-
- :switch:`--contract`
- Report the number of public subprograms with contracts
-
-
- :switch:`--no-contract`
- Do not report the number of public subprograms with contracts
-
-
- :switch:`--post`
- Report the number of public subprograms with postconditions
-
-
- :switch:`--no-post`
- Do not report the number of public subprograms with postconditions
-
-
- :switch:`--contract-complete`
- Report the number of public subprograms with complete contracts
-
-
- :switch:`--no-contract-complete`
- Do not report the number of public subprograms with complete contracts
-
-
- :switch:`--contract-cyclomatic`
- Report the McCabe complexity of public subprograms
-
-
- :switch:`--no-contract-cyclomatic`
- Do not report the McCabe complexity of public subprograms
-
-
- .. _Complexity_Metrics_Control:
-
- Complexity Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Complexity metrics control in gnatmetric
-
- For a program unit that is an executable body (a subprogram body
- (including generic bodies), task body, entry body or a package body
- containing its own statement sequence) ``gnatmetric`` computes the
- following complexity metrics:
-
- * McCabe cyclomatic complexity;
-
- * McCabe essential complexity;
-
- * maximal loop nesting level;
-
- * extra exit points (for subprograms);
-
- The McCabe cyclomatic complexity metric is defined
- in `http://www.mccabe.com/pdf/mccabe-nist235r.pdf <http://www.mccabe.com/pdf/mccabe-nist235r.pdf>`_
-
- According to McCabe, both control statements and short-circuit control
- forms should be taken into account when computing cyclomatic
- complexity. For Ada 2012 we have also take into account conditional
- expressions and quantified expressions. For each body, we compute
- three metric values:
-
- * the complexity introduced by control
- statements only, without taking into account short-circuit forms
- (referred as ``statement complexity`` in ``gnatmetric`` output),
-
- * the complexity introduced by short-circuit control forms only
- (referred as ``expression complexity`` in ``gnatmetric`` output),
- and
-
- * the total
- cyclomatic complexity, which is the sum of these two values
- (referred as ``cyclomatic complexity`` in ``gnatmetric`` output).
-
- The cyclomatic complexity is also computed for Ada 2012 expression functions.
- An expression function cannot have statements as its components, so only one
- metric value is computed as a cyclomatic complexity of an expression function.
-
- The origin of cyclomatic complexity metric is the need to estimate the number
- of independent paths in the control flow graph that in turn gives the number
- of tests needed to satisfy paths coverage testing completeness criterion.
- Considered from the testing point of view, a static Ada ``loop`` (that is,
- the ``loop`` statement having static subtype in loop parameter
- specification) does not add to cyclomatic complexity. By providing
- :switch:`--no-static-loop` option a user
- may specify that such loops should not be counted when computing the
- cyclomatic complexity metric
-
- The Ada essential complexity metric is a McCabe cyclomatic complexity metric
- counted for the code that is reduced by excluding all the pure structural Ada
- control statements. An compound statement is considered as a non-structural
- if it contains a ``raise`` or ``return`` statement as it subcomponent,
- or if it contains a ``goto`` statement that transfers the control outside
- the operator. A selective ``accept`` statement with a ``terminate`` alternative
- is considered a non-structural statement. When computing this metric,
- ``exit`` statements are treated in the same way as ``goto``
- statements unless the :switch:`-ne` option is specified.
-
- The Ada essential complexity metric defined here is intended to quantify
- the extent to which the software is unstructured. It is adapted from
- the McCabe essential complexity metric defined in
- http://www.mccabe.com/pdf/mccabe-nist235r.pdf
- but is modified to be more
- suitable for typical Ada usage. For example, short circuit forms
- are not penalized as unstructured in the Ada essential complexity metric.
-
- When computing cyclomatic and essential complexity, ``gnatmetric`` skips
- the code in the exception handlers and in all the nested program units. The
- code of assertions and predicates (that is, subprogram preconditions and
- postconditions, subtype predicates and type invariants) is also skipped.
-
- By default, all the complexity metrics are reported. For more fine-grained
- control you can use the following switches:
-
-
- .. index:: --complexity (gnatmetric)
- .. index:: --no-complexity (gnatmetric)
-
-
- :switch:`--complexity-all`
- Report all the complexity metrics
-
-
- :switch:`--no-complexity-all`
- Do not report any of the complexity metrics
-
-
- :switch:`--complexity-cyclomatic`
- Report the McCabe Cyclomatic Complexity
-
-
- :switch:`--no-complexity-cyclomatic`
- Do not report the McCabe Cyclomatic Complexity
-
-
- :switch:`--complexity-essential`
- Report the Essential Complexity
-
-
- :switch:`--no-complexity-essential`
- Do not report the Essential Complexity
-
-
- :switch:`--loop-nesting`
- Report maximal loop nesting level
-
-
- :switch:`--no-loop-nesting`
- Do not report maximal loop nesting level
-
-
- :switch:`--complexity-average`
- Report the average McCabe Cyclomatic Complexity for all the subprogram bodies,
- task bodies, entry bodies and statement sequences in package bodies.
- The metric is reported for whole set of processed Ada sources only.
-
-
- :switch:`--no-complexity-average`
- Do not report the average McCabe Cyclomatic Complexity for all the subprogram
- bodies, task bodies, entry bodies and statement sequences in package bodies
-
- .. index:: --no-treat-exit-as-goto (gnatmetric)
-
-
- :switch:`--no-treat-exit-as-goto`
- Do not consider ``exit`` statements as ``goto``\ s when
- computing Essential Complexity
-
- .. index:: --no-static-loop (gnatmetric)
-
-
- :switch:`--no-static-loop`
- Do not consider static loops when computing cyclomatic complexity
-
-
- :switch:`--extra-exit-points`
- Report the extra exit points for subprogram bodies. As an exit point, this
- metric counts ``return`` statements and raise statements in case when the
- raised exception is not handled in the same body. In case of a function this
- metric subtracts 1 from the number of exit points, because a function body
- must contain at least one ``return`` statement.
-
-
- :switch:`--no-extra-exit-points`
- Do not report the extra exit points for subprogram bodies
-
-
- .. _Coupling_Metrics_Control:
-
- Coupling Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Coupling metrics control in gnatmetric
-
- .. index:: Coupling metrics (in gnatmetric)
-
- Coupling metrics measure the dependencies between a given entity and other
- entities in the program. This information is useful since high coupling
- may signal potential issues with maintainability as the program evolves.
-
- ``gnatmetric`` computes the following coupling metrics:
-
-
- * *object-oriented coupling*, for classes in traditional object-oriented
- sense;
-
- * *unit coupling*, for all the program units making up a program;
-
- * *control coupling*, reflecting dependencies between a unit and
- other units that contain subprograms.
-
- .. index:: fan-out coupling
- .. index:: efferent coupling
-
- Two kinds of coupling metrics are computed:
-
- * fan-out coupling ('efferent coupling'):
- the number of entities the given entity depends upon. This metric
- reflects how the given entity depends on the changes in the
- 'external world'.
-
- .. index:: fan-in coupling
- .. index:: afferent coupling
-
- * fan-in coupling ('afferent' coupling):
- the number of entities that depend on a given entity.
- This metric reflects how the 'external world' depends on the changes in a
- given entity.
-
- Object-oriented coupling metrics measure the dependencies
- between a given class (or a group of classes) and the other classes in the
- program. In this subsection the term 'class' is used in its traditional
- object-oriented programming sense (an instantiable module that contains data
- and/or method members). A *category* (of classes) is a group of closely
- related classes that are reused and/or modified together.
-
- A class ``K``\ 's fan-out coupling is the number of classes
- that ``K`` depends upon.
- A category's fan-out coupling is the number of classes outside the
- category that the classes inside the category depend upon.
-
- A class ``K``\ 's fan-in coupling is the number of classes
- that depend upon ``K``.
- A category's fan-in coupling is the number of classes outside the
- category that depend on classes belonging to the category.
-
- Ada's object-oriented paradigm separates the instantiable entity
- (type) from the module (package), so the definition of the coupling
- metrics for Ada maps the class and class category notions
- onto Ada constructs.
-
- For the coupling metrics, several kinds of modules that define a tagged type
- or an interface type -- library packages, library generic packages, and
- library generic package instantiations -- are considered to be classes.
- A category consists of a library package (or
- a library generic package) that defines a tagged or an interface type,
- together with all its descendant (generic) packages that define tagged
- or interface types. Thus a
- category is an Ada hierarchy of library-level program units. Class
- coupling in Ada is referred to as 'tagged coupling', and category coupling
- is referred to as 'hierarchy coupling'.
-
- For any package serving as a class, its body and subunits (if any) are
- considered together with its spec when computing dependencies, and coupling
- metrics are reported for spec units only. Dependencies between classes
- mean Ada semantic dependencies. For object-oriented coupling
- metrics, only dependencies on units treated as classes are
- considered.
-
- Similarly, for unit and control coupling an entity is considered to be the
- conceptual construct consisting of the entity's specification, body, and
- any subunits (transitively).
- ``gnatmetric`` computes
- the dependencies of all these units as a whole, but
- metrics are only reported for spec
- units (or for a subprogram body unit in case if there is no
- separate spec for the given subprogram).
-
- For unit coupling, dependencies are computed between all kinds of program
- units. For control coupling, the dependencies of a given unit are limited to
- those units that define subprograms. Thus control fan-out coupling is reported
- for all units, but control fan-in coupling is only reported for units
- that define subprograms.
-
- The following simple example illustrates the difference between unit coupling
- and control coupling metrics:
-
- .. code-block:: ada
-
- package Lib_1 is
- function F_1 (I : Integer) return Integer;
- end Lib_1;
-
- package Lib_2 is
- type T_2 is new Integer;
- end Lib_2;
-
- package body Lib_1 is
- function F_1 (I : Integer) return Integer is
- begin
- return I + 1;
- end F_1;
- end Lib_1;
-
- with Lib_2; use Lib_2;
- package Pack is
- Var : T_2;
- function Fun (I : Integer) return Integer;
- end Pack;
-
- with Lib_1; use Lib_1;
- package body Pack is
- function Fun (I : Integer) return Integer is
- begin
- return F_1 (I);
- end Fun;
- end Pack;
-
- If we apply ``gnatmetric`` with the :switch:`--coupling-all` option to
- these units, the result will be:
-
- ::
-
- Coupling metrics:
- =================
- Unit Lib_1 (C:\\customers\\662\\L406-007\\lib_1.ads)
- control fan-out coupling : 0
- control fan-in coupling : 1
- unit fan-out coupling : 0
- unit fan-in coupling : 1
-
- Unit Pack (C:\\customers\\662\\L406-007\\pack.ads)
- control fan-out coupling : 1
- control fan-in coupling : 0
- unit fan-out coupling : 2
- unit fan-in coupling : 0
-
- Unit Lib_2 (C:\\customers\\662\\L406-007\\lib_2.ads)
- control fan-out coupling : 0
- unit fan-out coupling : 0
- unit fan-in coupling : 1
-
- The result does not contain values for object-oriented
- coupling because none of the argument units contains a tagged type and
- therefore none of these units can be treated as a class.
-
- The ``Pack`` package (spec and body) depends on two
- units -- ``Lib_1`` and ``Lib_2`` -- and so its unit fan-out coupling
- is 2. Since nothing depends on it, its unit fan-in coupling is 0, as
- is its control fan-in coupling. Only one of the units ``Pack`` depends
- upon defines a subprogram, so its control fan-out coupling is 1.
-
- ``Lib_2`` depends on nothing, so its fan-out metrics are 0. It does
- not define any subprograms, so it has no control fan-in metric.
- One unit (``Pack``) depends on it , so its unit fan-in coupling is 1.
-
- ``Lib_1`` is similar to ``Lib_2``, but it does define a subprogram.
- Its control fan-in coupling is 1 (because there is one unit
- depending on it).
-
- When computing coupling metrics, ``gnatmetric`` counts only
- dependencies between units that are arguments of the ``gnatmetric``
- invocation. Coupling metrics are program-wide (or project-wide) metrics, so
- you should invoke ``gnatmetric`` for
- the complete set of sources comprising your program. This can be done
- by invoking ``gnatmetric`` with the corresponding project file
- and with the :switch:`-U` option.
-
- By default, all the coupling metrics are reported. You can use the following
- switches to select specific syntax metrics.
-
- .. index:: --tagged-coupling (gnatmetric)
- .. index:: --hierarchy-coupling (gnatmetric)
- .. index:: --unit-coupling (gnatmetric)
- .. index:: --control-coupling (gnatmetric)
-
- :switch:`--coupling-all`
- Report all the coupling metrics
-
-
- :switch:`--tagged-coupling-out`
- Report tagged (class) fan-out coupling
-
-
- :switch:`--tagged-coupling-in`
- Report tagged (class) fan-in coupling
-
-
- :switch:`--hierarchy-coupling-out`
- Report hierarchy (category) fan-out coupling
-
-
- :switch:`--hierarchy-coupling-in`
- Report hierarchy (category) fan-in coupling
-
-
- :switch:`--unit-coupling-out`
- Report unit fan-out coupling
-
-
- :switch:`--unit-coupling-in`
- Report unit fan-in coupling
-
-
- :switch:`--control-coupling-out`
- Report control fan-out coupling
-
-
- :switch:`--control-coupling-in`
- Report control fan-in coupling
-
-
- .. _Other_gnatmetric_Switches:
-
- Other ``gnatmetric`` Switches
- -----------------------------
-
- Additional ``gnatmetric`` switches are as follows:
-
-
- .. index:: --version (gnatmetric)
-
- :switch:`--version`
- Display copyright and version, then exit disregarding all other options.
-
-
- .. index:: --help (gnatmetric)
-
- :switch:`--help`
- Display usage, then exit disregarding all other options.
-
-
- .. index:: -P (gnatmetric)
-
- :switch:`-P {file}`
- Indicates the name of the project file that describes the set of sources
- to be processed. The exact set of argument sources depends on other options
- specified, see below. An aggregate project is allowed as the file parameter
- only if it has exactly one non-aggregate project being aggregated.
-
-
- .. index:: -U (gnatmetric)
-
- :switch:`-U`
- If a project file is specified and no argument source is explicitly
- specified (either directly or by means of :switch:`-files` option), process
- all the units of the closure of the argument project. Otherwise this option
- has no effect.
-
-
- :switch:`-U {main_unit}`
- If a project file is specified and no argument source is explicitly
- specified (either directly or by means of :switch:`-files` option), process
- the closure of units rooted at ``main_unit``. Otherwise this option
- has no effect.
-
-
- .. index:: -X (gnatmetric)
-
- :switch:`-X{name}={value}`
- Indicates that external variable ``name`` in the argument project
- has the value ``value``. Has no effect if no project is specified.
-
-
- .. index:: --RTS (gnatmetric)
-
- :switch:`--RTS={rts-path}`
- Specifies the default location of the runtime library. Same meaning as the
- equivalent ``gnatmake`` flag (see :ref:`Switches_for_gnatmake`).
-
-
- .. index:: --subdirs=dir (gnatmetric)
-
- :switch:`--subdirs={dir}`
- Use the specified subdirectory of the project objects file (or of the
- project file directory if the project does not specify an object directory)
- for tool output files. Has no effect if no project is specified as
- tool argument r if :switch:`--no-objects-dir` is specified.
-
-
- .. index:: --files (gnatmetric)
-
- :switch:`--files={file}`
- Take as arguments the files listed in text file ``file``.
- Text file ``file`` may contain empty lines that are ignored.
- Each nonempty line should contain the name of an existing file.
- Several such switches may be specified simultaneously.
-
-
- .. index:: --ignore (gnatmetric)
-
- :switch:`--ignore={filename}`
- Do not process the sources listed in a specified file.
-
-
- .. index:: --verbose (gnatmetric)
-
- :switch:`--verbose`
- Verbose mode;
- ``gnatmetric`` generates version information and then
- a trace of sources being processed.
-
-
- .. index:: --quiet (gnatmetric)
-
- :switch:`--quiet`
- Quiet mode.
-
- If a project file is specified and no argument source is explicitly
- specified (either directly or by means of :switch:`-files` option), and no
- :switch:`-U` is specified, then the set of processed sources is
- all the immediate units of the argument project.
-
-
- Legacy Switches
- ^^^^^^^^^^^^^^^
-
- Some switches have a short form, mostly for legacy reasons,
- as shown below.
-
- .. index:: -x (gnatmetric)
-
- :switch:`-x`
- :switch:`--generate-xml-output`
-
- .. index:: -xs (gnatmetric)
-
- :switch:`-xs`
- :switch:`--generate-xml-schema`
-
- .. index:: -nt (gnatmetric)
-
- :switch:`-nt`
- :switch:`--no-text-output`
-
- .. index:: -d (gnatmetric)
-
- :switch:`-d {output-dir}`
- :switch:`--output-dir`
-
- .. index:: -o (gnatmetric)
-
- :switch:`-o {file-suffix}`
- :switch:`--output-suffix`
-
- .. index:: -og (gnatmetric)
-
- :switch:`-og {file-name}`
- :switch:`--global-file-name`
-
- .. index:: -ox (gnatmetric)
-
- :switch:`-ox {file-name}`
- :switch:`--xml-file-name`
-
- .. index:: -sfn (gnatmetric)
-
- :switch:`-sfn`
- :switch:`--short-file-names`
-
- .. index:: -W (gnatsmetric)
-
- :switch:`-W{e}`
- :switch:`--wide-character-encoding={e}`
-
- .. index:: -nolocal (gnatmetric)
-
- :switch:`-nolocal`
- :switch:`--no-local-metrics`
-
- .. index:: -ne (gnatmetric)
-
- :switch:`-ne`
- :switch:`--no-treat-exit-as-goto`
-
- .. index:: -files (gnatmetric)
-
- :switch:`-files {filename}`
- :switch:`--files`
-
- .. index:: -v (gnatmetric)
-
- :switch:`-v`
- :switch:`--verbose`
-
- .. index:: -q (gnatmetric)
-
- :switch:`-q`
- :switch:`--quiet`
-
.. only:: PRO or GPL
.. _The_GNAT_Pretty_Printer_gnatpp:
@@ -3026,7 +1908,7 @@ building specialized scripts.
naming conventions.
Note that it is no longer necessary to specify the Ada language version;
- ``gnatmetric`` can process Ada source code written in any version from
+ ``gnatstub`` can process Ada source code written in any version from
Ada 83 onward without specifying any language version switch.
* *switches*
diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
index b1889fe..48fb107 100644
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -42,17 +42,13 @@
#include "adaint.h"
#include <sys/types.h>
-#ifdef __MINGW32__
-# if OLD_MINGW
-# include <sys/wait.h>
-# endif
-#elif defined (__vxworks) && defined (__RTP__)
+#if defined (__vxworks) && defined (__RTP__)
# include <wait.h>
#elif defined (__Lynx__)
/* ??? See comment in adaint.c. */
# define GCC_RESOURCE_H
# include <sys/wait.h>
-#elif defined (__PikeOS__)
+#elif defined (__PikeOS__) || defined (__MINGW32__)
/* No wait.h available */
#else
#include <sys/wait.h>
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index cdf8605..64f2e79 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT Reference Manual , Sep 09, 2022
+GNAT Reference Manual , Sep 23, 2022
AdaCore
@@ -433,7 +433,7 @@ Implementation Defined Attributes
* Attribute Universal_Literal_String::
* Attribute Unrestricted_Access::
* Attribute Update::
-* Attribute Valid_Image::
+* Attribute Valid_Value::
* Attribute Valid_Scalars::
* Attribute VADS_Size::
* Attribute Value_Size::
@@ -10295,7 +10295,7 @@ consideration, you should minimize the use of these attributes.
* Attribute Universal_Literal_String::
* Attribute Unrestricted_Access::
* Attribute Update::
-* Attribute Valid_Image::
+* Attribute Valid_Value::
* Attribute Valid_Scalars::
* Attribute VADS_Size::
* Attribute Value_Size::
@@ -12040,7 +12040,7 @@ In general this is a risky approach. It may appear to “work” but such uses o
@code{Unrestricted_Access} are potentially non-portable, even from one version
of GNAT to another, so are best avoided if possible.
-@node Attribute Update,Attribute Valid_Image,Attribute Unrestricted_Access,Implementation Defined Attributes
+@node Attribute Update,Attribute Valid_Value,Attribute Unrestricted_Access,Implementation Defined Attributes
@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1ac}
@section Attribute Update
@@ -12121,19 +12121,19 @@ A := A'Update ((1, 2) => 20, (3, 4) => 30);
which changes element (1,2) to 20 and (3,4) to 30.
-@node Attribute Valid_Image,Attribute Valid_Scalars,Attribute Update,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-valid-image}@anchor{1ad}
-@section Attribute Valid_Image
+@node Attribute Valid_Value,Attribute Valid_Scalars,Attribute Update,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-valid-value}@anchor{1ad}
+@section Attribute Valid_Value
-@geindex Valid_Image
+@geindex Valid_Value
-The @code{'Valid_Image} attribute is defined for enumeration types other than
+The @code{'Valid_Value} attribute is defined for enumeration types other than
those in package Standard. This attribute is a function that takes
-a String, and returns Boolean. @code{T'Valid_Image (S)} returns True
+a String, and returns Boolean. @code{T'Valid_Value (S)} returns True
if and only if @code{T'Value (S)} would not raise Constraint_Error.
-@node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Valid_Image,Implementation Defined Attributes
+@node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Valid_Value,Implementation Defined Attributes
@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1ae}
@section Attribute Valid_Scalars
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index f2cb1ed..7d96dbe 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Sep 09, 2022
+GNAT User's Guide for Native Platforms , Sep 26, 2022
AdaCore
@@ -9220,6 +9220,7 @@ Float_Size : Pos; -- Standard.Float'Size
Float_Words_BE : Nat; -- Float words stored big-endian?
Int_Size : Pos; -- Standard.Integer'Size
Long_Double_Size : Pos; -- Standard.Long_Long_Float'Size
+Long_Long_Long_Size : Pos; -- Standard.Long_Long_Long_Integer'Size
Long_Long_Size : Pos; -- Standard.Long_Long_Integer'Size
Long_Size : Pos; -- Standard.Long_Integer'Size
Maximum_Alignment : Pos; -- Maximum permitted alignment
@@ -9307,6 +9308,7 @@ Float_Size 32
Float_Words_BE 0
Int_Size 64
Long_Double_Size 128
+Long_Long_Long_Size 128
Long_Long_Size 64
Long_Size 64
Maximum_Alignment 16
@@ -15317,10 +15319,11 @@ Linker switches can be specified after @code{-largs} builder switch.
@item @code{-fuse-ld=`name'}
-Linker to be used. The default is @code{bfd} for @code{ld.bfd},
-the alternative being @code{gold} for @code{ld.gold}. The later is
-a more recent and faster linker, but only available on GNU/Linux
+Linker to be used. The default is @code{bfd} for @code{ld.bfd}; @code{gold}
+(for @code{ld.gold}) and @code{mold} (for @code{ld.mold}) are more
+recent and faster alternatives, but only available on GNU/Linux
platforms.
+
@end table
@node Binding with gnatbind,Linking with gnatlink,Linker Switches,Building Executable Programs with GNAT
@@ -17932,7 +17935,6 @@ instr.ads
-
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node GNAT and Program Execution,Platform-Specific Information,GNAT Utility Programs,Top
diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h
index e7284a1..561f2ff 100644
--- a/gcc/ada/gsocket.h
+++ b/gcc/ada/gsocket.h
@@ -80,12 +80,6 @@
#define FD_SETSIZE 1024
#ifdef __MINGW32__
-/* winsock2.h allows WSAPoll related definitions only when
- * _WIN32_WINNT >= 0x0600 */
-#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
-#define _WIN32_WINNT 0x0600
-#endif
-
#include <winsock2.h>
#include <ws2tcpip.h>
#include <versionhelpers.h>
diff --git a/gcc/ada/mingw32.h b/gcc/ada/mingw32.h
index 1157fc6..d038211 100644
--- a/gcc/ada/mingw32.h
+++ b/gcc/ada/mingw32.h
@@ -44,11 +44,6 @@
#define UNICODE /* For Win32 API */
#endif
-/* We need functionality available only starting with Windows XP */
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
#ifndef __CYGWIN__
#include <tchar.h>
#endif
@@ -99,27 +94,4 @@ extern UINT __gnat_current_ccs_encoding;
#define WS2S(str,wstr,len) strncpy(str,wstr,len)
#endif
-#include <stdlib.h>
-
-/* STD_MINGW: standard if MINGW32 version > 1.3, we have switched to this
- version instead of the previous enhanced version to ease building GNAT on
- Windows platforms. By using STD_MINGW or OLD_MINGW it is possible to build
- GNAT using both MingW include files (Old MingW + ACT changes and standard
- MingW starting with version 1.3.
- For w64 Mingw the define STD_MINGW is always set to value 1, because
- there is no old header set present. */
-#ifdef _WIN64
-#define STD_MINGW 1
-#else
-#define STD_MINGW ((__MINGW32_MAJOR_VERSION == 1 \
- && __MINGW32_MINOR_VERSION >= 3) \
- || (__MINGW32_MAJOR_VERSION >= 2))
-#endif
-
-#define OLD_MINGW (!(STD_MINGW))
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN MAX_PATH
-#endif
-
#endif /* _MINGW32_H */
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 65c6409..24aca2c 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -189,7 +189,6 @@ package Rtsfind is
-- Children of Interfaces
Interfaces_C,
- Interfaces_Packed_Decimal,
-- Children of Interfaces.C
@@ -205,7 +204,6 @@ package Rtsfind is
System_Address_To_Access_Conversions,
System_Arith_64,
System_Arith_128,
- System_AST_Handling,
System_Assertions,
System_Atomic_Operations,
System_Atomic_Primitives,
@@ -257,9 +255,6 @@ package Rtsfind is
System_Fat_LFlt,
System_Fat_LLF,
System_Fat_SFlt,
- System_Fat_VAX_D_Float,
- System_Fat_VAX_F_Float,
- System_Fat_VAX_G_Float,
System_Finalization_Masters,
System_Finalization_Root,
System_Fore_Decimal_32,
@@ -288,14 +283,12 @@ package Rtsfind is
System_Img_LLLI,
System_Img_LLU,
System_Img_LLLU,
- System_Img_Name,
System_Img_Uns,
System_Img_WChar,
System_Interrupts,
System_Long_Long_Float_Expon,
System_Machine_Code,
System_Mantissa,
- System_Memcop,
System_Memory,
System_Multiprocessors,
System_Pack_03,
@@ -420,10 +413,7 @@ package Rtsfind is
System_Pack_127,
System_Parameters,
System_Partition_Interface,
- System_Pool_32_Global,
System_Pool_Global,
- System_Pool_Empty,
- System_Pool_Local,
System_Pool_Size,
System_Put_Images,
System_Put_Task_Images,
@@ -440,7 +430,6 @@ package Rtsfind is
System_Stream_Attributes,
System_Task_Info,
System_Tasking,
- System_Threads,
System_Unsigned_Types,
System_Val_Bool,
System_Val_Char,
@@ -461,7 +450,6 @@ package Rtsfind is
System_Val_LLLI,
System_Val_LLU,
System_Val_LLLU,
- System_Val_Name,
System_Val_Uns,
System_Val_WChar,
System_Version_Control,
@@ -475,7 +463,6 @@ package Rtsfind is
System_Wid_LLLI,
System_Wid_LLU,
System_Wid_LLLU,
- System_Wid_Name,
System_Wid_Uns,
System_Wid_WChar,
System_WWd_Char,
@@ -484,7 +471,7 @@ package Rtsfind is
-- Children of System.Atomic_Operations
- System_Atomic_Operations_Test_And_Set,
+ System_Atomic_Operations_Test_And_Set,
-- Children of System.Dim
@@ -561,17 +548,13 @@ package Rtsfind is
RE_Set_Deadline, -- Ada.Dispatching.EDF
- RE_Code_Loc, -- Ada.Exceptions
RE_Exception_Id, -- Ada.Exceptions
- RE_Exception_Identity, -- Ada.Exceptions
RE_Exception_Information, -- Ada.Exceptions
RE_Exception_Message, -- Ada.Exceptions
RE_Exception_Name_Simple, -- Ada.Exceptions
RE_Exception_Occurrence, -- Ada.Exceptions
- RE_Exception_Occurrence_Access, -- Ada.Exceptions
RE_Null_Id, -- Ada.Exceptions
RE_Null_Occurrence, -- Ada.Exceptions
- RE_Poll, -- Ada.Exceptions
RE_Raise_Exception, -- Ada.Exceptions
RE_Raise_Exception_Always, -- Ada.Exceptions
RE_Raise_From_Controlled_Operation, -- Ada.Exceptions
@@ -596,7 +579,7 @@ package Rtsfind is
RE_Names, -- Ada.Interrupts.Names
RE_Clock, -- Ada.Real_Time
- RE_Clock_Time, -- Ada.Real_Time
+ RE_Clock_Time, -- Ada.Real_Time [used by GNATprove]
RE_Time_Span, -- Ada.Real_Time
RE_Time_Span_Zero, -- Ada.Real_Time
RO_RT_Time, -- Ada.Real_Time
@@ -612,8 +595,6 @@ package Rtsfind is
RE_Stream_Element_Array, -- Ada.Streams
RE_Stream_Element_Offset, -- Ada.Streams
- RE_Stream_Access, -- Ada.Streams.Stream_IO
-
RO_SU_Super_String, -- Ada.Strings.Superbounded
RO_WI_Super_String, -- Ada.Strings.Wide_Superbounded
@@ -628,8 +609,6 @@ package Rtsfind is
RE_Buffer_Type, -- Ada.Strings.Text_Buffers.Unbounded
RE_Get, -- Ada.Strings.Text_Buffers.Unbounded
- RE_Wide_Get, -- Ada.Strings.Text_Buffers.Unbounded
- RE_Wide_Wide_Get, -- Ada.Strings.Text_Buffers.Unbounded
RE_Wait_For_Release, -- Ada.Synchronous_Barriers
@@ -641,7 +620,6 @@ package Rtsfind is
RE_Address_Array, -- Ada.Tags
RE_Addr_Ptr, -- Ada.Tags
RE_Base_Address, -- Ada.Tags
- RE_Check_Interface_Conversion, -- Ada.Tags
RE_Check_TSD, -- Ada.Tags
RE_Cstring_Ptr, -- Ada.Tags
RE_CW_Membership, -- Ada.Tags
@@ -656,13 +634,11 @@ package Rtsfind is
RE_External_Tag, -- Ada.Tags
RO_TA_External_Tag, -- Ada.Tags
RE_Get_Access_Level, -- Ada.Tags
- RE_Get_Alignment, -- Ada.Tags
RE_Get_Entry_Index, -- Ada.Tags
RE_Get_Offset_Index, -- Ada.Tags
RE_Get_Prim_Op_Kind, -- Ada.Tags
RE_Get_Tagged_Kind, -- Ada.Tags
RE_HT_Link, -- Ada.Tags
- RE_Idepth, -- Ada.Tags
RE_Interfaces_Array, -- Ada.Tags
RE_Interfaces_Table, -- Ada.Tags
RE_Interface_Data, -- Ada.Tags
@@ -675,8 +651,6 @@ package Rtsfind is
RE_No_Dispatch_Table_Wrapper, -- Ada.Tags
RE_No_Tag, -- Ada.Tags
RE_NDT_Prims_Ptr, -- Ada.Tags
- RE_NDT_TSD, -- Ada.Tags
- RE_Num_Prims, -- Ada.Tags
RE_Object_Specific_Data, -- Ada.Tags
RE_Offset_To_Top, -- Ada.Tags
RE_Offset_To_Top_Ptr, -- Ada.Tags
@@ -699,11 +673,9 @@ package Rtsfind is
RE_Primary_DT, -- Ada.Tags
RE_Signature, -- Ada.Tags
RE_SSD, -- Ada.Tags
- RE_TSD, -- Ada.Tags
RE_Type_Specific_Data, -- Ada.Tags
RE_Register_Interface_Offset, -- Ada.Tags
RE_Register_Tag, -- Ada.Tags
- RE_Register_TSD, -- Ada.Tags
RE_Transportable, -- Ada.Tags
RE_Secondary_DT, -- Ada.Tags
RE_Secondary_Tag, -- Ada.Tags
@@ -749,7 +721,6 @@ package Rtsfind is
RE_Stream_T, -- CUDA.Driver_Types
- RE_Fatbin_Wrapper, -- CUDA.Internal
RE_Launch_Kernel, -- CUDA.Internal
RE_Pop_Call_Configuration, -- CUDA.Internal
RE_Push_Call_Configuration, -- CUDA.Internal
@@ -772,19 +743,14 @@ package Rtsfind is
RO_IC_Unsigned, -- Interfaces.C
- RE_Chars_Ptr, -- Interfaces.C.Strings
- RE_New_Char_Array, -- Interfaces.C.Strings
-
RE_Address, -- System
RE_Any_Priority, -- System
RE_Bit_Order, -- System
RE_Default_Priority, -- System
RE_High_Order_First, -- System
RE_Interrupt_Priority, -- System
- RE_Lib_Stop, -- System
RE_Low_Order_First, -- System
RE_Max_Base_Digits, -- System
- RE_Max_Priority, -- System
RE_Null_Address, -- System
RE_Priority, -- System
@@ -802,8 +768,6 @@ package Rtsfind is
RE_Subtract_With_Ovflo_Check128, -- System.Arith_128
RE_Scaled_Divide128, -- System.Arith_128
- RE_Create_AST_Handler, -- System.AST_Handling
-
RE_Assert_Failure, -- System.Assertions
RE_Raise_Assert_Failure, -- System.Assertions
@@ -824,9 +788,6 @@ package Rtsfind is
RE_Atomic_Test_And_Set, -- System.Atomic_Operations.Test_And_Set
RE_AST_Handler, -- System.Aux_DEC
- RE_Import_Address, -- System.Aux_DEC
- RE_Import_Value, -- System.Aux_DEC
- RE_No_AST_Handler, -- System.Aux_DEC
RE_Type_Class, -- System.Aux_DEC
RE_Type_Class_Enumeration, -- System.Aux_DEC
RE_Type_Class_Integer, -- System.Aux_DEC
@@ -954,15 +915,6 @@ package Rtsfind is
RE_Attr_Long_Long_Float, -- System.Fat_LLF
- RE_Attr_VAX_D_Float, -- System.Fat_VAX_D_Float
- RE_Fat_VAX_D, -- System.Fat_VAX_D_Float
-
- RE_Attr_VAX_F_Float, -- System.Fat_VAX_F_Float
- RE_Fat_VAX_F, -- System.Fat_VAX_F_Float
-
- RE_Attr_VAX_G_Float, -- System.Fat_VAX_G_Float
- RE_Fat_VAX_G, -- System.Fat_VAX_G_Float
-
RE_Add_Offset_To_Address, -- System.Finalization_Masters
RE_Attach, -- System.Finalization_Masters
RE_Base_Pool, -- System.Finalization_Masters
@@ -970,10 +922,8 @@ package Rtsfind is
RE_Finalization_Master_Ptr, -- System.Finalization_Masters
RE_Set_Base_Pool, -- System.Finalization_Masters
RE_Set_Finalize_Address, -- System.Finalization_Masters
- RE_Set_Is_Heterogeneous, -- System.Finalization_Masters
RE_Root_Controlled, -- System.Finalization_Root
- RE_Root_Controlled_Ptr, -- System.Finalization_Root
RE_Fore_Decimal32, -- System.Fore_Decimal_32
@@ -1649,9 +1599,7 @@ package Rtsfind is
RE_Set_127, -- System.Pack_127
RE_Adjust_Storage_Size, -- System.Parameters
- RE_Default_Secondary_Stack_Size, -- System.Parameters
RE_Default_Stack_Size, -- System.Parameters
- RE_Garbage_Collected, -- System.Parameters
RE_Size_Type, -- System.Parameters
RE_Unspecified_Size, -- System.Parameters
@@ -1677,8 +1625,6 @@ package Rtsfind is
RE_Global_Pool_Object, -- System.Pool_Global
- RE_Global_Pool_32_Object, -- System.Pool_32_Global
-
RE_Stack_Bounded_Pool, -- System.Pool_Size
RE_Put_Image_Integer, -- System.Put_Images
@@ -1744,11 +1690,8 @@ package Rtsfind is
RE_Set_Result, -- System.Partition_Interface
RE_Register_Obj_Receiving_Stub, -- System.Partition_Interface
RE_Register_Pkg_Receiving_Stub, -- System.Partition_Interface
- RE_Is_Nil, -- System.Partition_Interface
- RE_Entity_Ptr, -- System.Partition_Interface
RE_Entity_Of, -- System.Partition_Interface
RE_Inc_Usage, -- System.Partition_Interface
- RE_Set_Ref, -- System.Partition_Interface
RE_Make_Ref, -- System.Partition_Interface
RE_Get_Local_Address, -- System.Partition_Interface
RE_Get_Reference, -- System.Partition_Interface
@@ -1881,8 +1824,6 @@ package Rtsfind is
RE_Deallocate_Any_Controlled, -- System.Storage_Pools.Subpools
RE_Header_Size_With_Padding, -- System.Storage_Pools.Subpools
RE_Root_Storage_Pool_With_Subpools, -- System.Storage_Pools.Subpools
- RE_Root_Subpool, -- System.Storage_Pools.Subpools
- RE_Subpool_Handle, -- System.Storage_Pools.Subpools
RE_I_AD, -- System.Stream_Attributes
RE_I_AS, -- System.Stream_Attributes
@@ -2006,7 +1947,6 @@ package Rtsfind is
RE_Simple_Mode, -- System.Tasking
RE_Terminate_Mode, -- System.Tasking
RE_Delay_Mode, -- System.Tasking
- RE_Entry_Index, -- System.Tasking
RE_Task_Entry_Index, -- System.Tasking
RE_Self, -- System.Tasking
@@ -2244,17 +2184,13 @@ package Rtsfind is
RE_Set_Deadline => Ada_Dispatching_EDF,
- RE_Code_Loc => Ada_Exceptions,
RE_Exception_Id => Ada_Exceptions,
- RE_Exception_Identity => Ada_Exceptions,
RE_Exception_Information => Ada_Exceptions,
RE_Exception_Message => Ada_Exceptions,
RE_Exception_Name_Simple => Ada_Exceptions,
RE_Exception_Occurrence => Ada_Exceptions,
- RE_Exception_Occurrence_Access => Ada_Exceptions,
RE_Null_Id => Ada_Exceptions,
RE_Null_Occurrence => Ada_Exceptions,
- RE_Poll => Ada_Exceptions,
RE_Raise_Exception => Ada_Exceptions,
RE_Raise_Exception_Always => Ada_Exceptions,
RE_Raise_From_Controlled_Operation => Ada_Exceptions,
@@ -2295,8 +2231,6 @@ package Rtsfind is
RE_Stream_Element_Array => Ada_Streams,
RE_Stream_Element_Offset => Ada_Streams,
- RE_Stream_Access => Ada_Streams_Stream_IO,
-
RO_SU_Super_String => Ada_Strings_Superbounded,
RO_WI_Super_String => Ada_Strings_Wide_Superbounded,
@@ -2311,8 +2245,6 @@ package Rtsfind is
RE_Buffer_Type => Ada_Strings_Text_Buffers_Unbounded,
RE_Get => Ada_Strings_Text_Buffers_Unbounded,
- RE_Wide_Get => Ada_Strings_Text_Buffers_Unbounded,
- RE_Wide_Wide_Get => Ada_Strings_Text_Buffers_Unbounded,
RE_Wait_For_Release => Ada_Synchronous_Barriers,
@@ -2324,7 +2256,6 @@ package Rtsfind is
RE_Address_Array => Ada_Tags,
RE_Addr_Ptr => Ada_Tags,
RE_Base_Address => Ada_Tags,
- RE_Check_Interface_Conversion => Ada_Tags,
RE_Check_TSD => Ada_Tags,
RE_Cstring_Ptr => Ada_Tags,
RE_CW_Membership => Ada_Tags,
@@ -2339,13 +2270,11 @@ package Rtsfind is
RE_External_Tag => Ada_Tags,
RO_TA_External_Tag => Ada_Tags,
RE_Get_Access_Level => Ada_Tags,
- RE_Get_Alignment => Ada_Tags,
RE_Get_Entry_Index => Ada_Tags,
RE_Get_Offset_Index => Ada_Tags,
RE_Get_Prim_Op_Kind => Ada_Tags,
RE_Get_Tagged_Kind => Ada_Tags,
RE_HT_Link => Ada_Tags,
- RE_Idepth => Ada_Tags,
RE_Interfaces_Array => Ada_Tags,
RE_Interfaces_Table => Ada_Tags,
RE_Interface_Data => Ada_Tags,
@@ -2358,8 +2287,6 @@ package Rtsfind is
RE_No_Dispatch_Table_Wrapper => Ada_Tags,
RE_No_Tag => Ada_Tags,
RE_NDT_Prims_Ptr => Ada_Tags,
- RE_NDT_TSD => Ada_Tags,
- RE_Num_Prims => Ada_Tags,
RE_Object_Specific_Data => Ada_Tags,
RE_Offset_To_Top => Ada_Tags,
RE_Offset_To_Top_Ptr => Ada_Tags,
@@ -2382,11 +2309,9 @@ package Rtsfind is
RE_Primary_DT => Ada_Tags,
RE_Signature => Ada_Tags,
RE_SSD => Ada_Tags,
- RE_TSD => Ada_Tags,
RE_Type_Specific_Data => Ada_Tags,
RE_Register_Interface_Offset => Ada_Tags,
RE_Register_Tag => Ada_Tags,
- RE_Register_TSD => Ada_Tags,
RE_Transportable => Ada_Tags,
RE_Secondary_DT => Ada_Tags,
RE_Secondary_Tag => Ada_Tags,
@@ -2432,7 +2357,6 @@ package Rtsfind is
RE_Stream_T => CUDA_Driver_Types,
- RE_Fatbin_Wrapper => CUDA_Internal,
RE_Launch_Kernel => CUDA_Internal,
RE_Pop_Call_Configuration => CUDA_Internal,
RE_Push_Call_Configuration => CUDA_Internal,
@@ -2455,19 +2379,14 @@ package Rtsfind is
RO_IC_Unsigned => Interfaces_C,
- RE_Chars_Ptr => Interfaces_C_Strings,
- RE_New_Char_Array => Interfaces_C_Strings,
-
RE_Address => System,
RE_Any_Priority => System,
RE_Bit_Order => System,
RE_Default_Priority => System,
RE_High_Order_First => System,
RE_Interrupt_Priority => System,
- RE_Lib_Stop => System,
RE_Low_Order_First => System,
RE_Max_Base_Digits => System,
- RE_Max_Priority => System,
RE_Null_Address => System,
RE_Priority => System,
@@ -2485,8 +2404,6 @@ package Rtsfind is
RE_Subtract_With_Ovflo_Check128 => System_Arith_128,
RE_Scaled_Divide128 => System_Arith_128,
- RE_Create_AST_Handler => System_AST_Handling,
-
RE_Assert_Failure => System_Assertions,
RE_Raise_Assert_Failure => System_Assertions,
@@ -2507,9 +2424,6 @@ package Rtsfind is
RE_Atomic_Test_And_Set => System_Atomic_Operations_Test_And_Set,
RE_AST_Handler => System_Aux_DEC,
- RE_Import_Address => System_Aux_DEC,
- RE_Import_Value => System_Aux_DEC,
- RE_No_AST_Handler => System_Aux_DEC,
RE_Type_Class => System_Aux_DEC,
RE_Type_Class_Enumeration => System_Aux_DEC,
RE_Type_Class_Integer => System_Aux_DEC,
@@ -2643,15 +2557,6 @@ package Rtsfind is
RE_Attr_Long_Long_Float => System_Fat_LLF,
- RE_Attr_VAX_D_Float => System_Fat_VAX_D_Float,
- RE_Fat_VAX_D => System_Fat_VAX_D_Float,
-
- RE_Attr_VAX_F_Float => System_Fat_VAX_F_Float,
- RE_Fat_VAX_F => System_Fat_VAX_F_Float,
-
- RE_Attr_VAX_G_Float => System_Fat_VAX_G_Float,
- RE_Fat_VAX_G => System_Fat_VAX_G_Float,
-
RE_Add_Offset_To_Address => System_Finalization_Masters,
RE_Attach => System_Finalization_Masters,
RE_Base_Pool => System_Finalization_Masters,
@@ -2659,10 +2564,8 @@ package Rtsfind is
RE_Finalization_Master_Ptr => System_Finalization_Masters,
RE_Set_Base_Pool => System_Finalization_Masters,
RE_Set_Finalize_Address => System_Finalization_Masters,
- RE_Set_Is_Heterogeneous => System_Finalization_Masters,
RE_Root_Controlled => System_Finalization_Root,
- RE_Root_Controlled_Ptr => System_Finalization_Root,
RE_Fore_Decimal32 => System_Fore_Decimal_32,
@@ -3340,9 +3243,7 @@ package Rtsfind is
RE_Set_127 => System_Pack_127,
RE_Adjust_Storage_Size => System_Parameters,
- RE_Default_Secondary_Stack_Size => System_Parameters,
RE_Default_Stack_Size => System_Parameters,
- RE_Garbage_Collected => System_Parameters,
RE_Size_Type => System_Parameters,
RE_Unspecified_Size => System_Parameters,
@@ -3399,11 +3300,8 @@ package Rtsfind is
RE_Set_Result => System_Partition_Interface,
RE_Register_Obj_Receiving_Stub => System_Partition_Interface,
RE_Register_Pkg_Receiving_Stub => System_Partition_Interface,
- RE_Is_Nil => System_Partition_Interface,
- RE_Entity_Ptr => System_Partition_Interface,
RE_Entity_Of => System_Partition_Interface,
RE_Inc_Usage => System_Partition_Interface,
- RE_Set_Ref => System_Partition_Interface,
RE_Make_Ref => System_Partition_Interface,
RE_Get_Local_Address => System_Partition_Interface,
RE_Get_Reference => System_Partition_Interface,
@@ -3488,8 +3386,6 @@ package Rtsfind is
RE_Global_Pool_Object => System_Pool_Global,
- RE_Global_Pool_32_Object => System_Pool_32_Global,
-
RE_Stack_Bounded_Pool => System_Pool_Size,
RE_Put_Image_Integer => System_Put_Images,
@@ -3572,8 +3468,6 @@ package Rtsfind is
RE_Deallocate_Any_Controlled => System_Storage_Pools_Subpools,
RE_Header_Size_With_Padding => System_Storage_Pools_Subpools,
RE_Root_Storage_Pool_With_Subpools => System_Storage_Pools_Subpools,
- RE_Root_Subpool => System_Storage_Pools_Subpools,
- RE_Subpool_Handle => System_Storage_Pools_Subpools,
RE_I_AD => System_Stream_Attributes,
RE_I_AS => System_Stream_Attributes,
@@ -3697,7 +3591,6 @@ package Rtsfind is
RE_Simple_Mode => System_Tasking,
RE_Terminate_Mode => System_Tasking,
RE_Delay_Mode => System_Tasking,
- RE_Entry_Index => System_Tasking,
RE_Task_Entry_Index => System_Tasking,
RE_Self => System_Tasking,
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index af69190..5394122 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -237,9 +237,6 @@ int counter = 0;
#define CST(name,comment) C(#name,String,name,comment)
/* String constant */
-#define STR(x) STR1(x)
-#define STR1(x) #x
-
#ifdef __MINGW32__
unsigned int _CRT_fmode = _O_BINARY;
#endif
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 9525140..ab2e182 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -6296,13 +6296,16 @@ package body Sem_Ch12 is
Old_Main : constant Entity_Id := Cunit_Entity (Main_Unit);
begin
- -- A new compilation unit node is built for the instance declaration
+ -- A new compilation unit node is built for the instance declaration.
+ -- It relocates the auxiliary declaration node from the compilation unit
+ -- where the instance appeared, so that declarations that originally
+ -- followed the instance will be attached to the spec compilation unit.
Decl_Cunit :=
Make_Compilation_Unit (Sloc (N),
Context_Items => Empty_List,
Unit => Act_Decl,
- Aux_Decls_Node => Make_Compilation_Unit_Aux (Sloc (N)));
+ Aux_Decls_Node => Relocate_Node (Aux_Decls_Node (Parent (N))));
Set_Parent_Spec (Act_Decl, Parent_Spec (N));
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 17bf6d9..d0f00b3 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -2429,13 +2429,9 @@ package body Sem_Ch5 is
if not Is_Entity_Name (Iter_Name)
- -- When the context is a quantified expression, the renaming
- -- declaration is delayed until the expansion phase if we are
- -- doing expansion.
+ -- Do not perform this expansion in preanalysis
- and then (Nkind (Parent (N)) /= N_Quantified_Expression
- or else (Operating_Mode = Check_Semantics
- and then not GNATprove_Mode))
+ and then Full_Analysis
-- Do not perform this expansion when expansion is disabled, where the
-- temporary may hide the transformation of a selected component into
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index b0babeb..9ae082c 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -531,7 +531,7 @@ package body Sem_Util is
-- Local variables
- E : Entity_Id := Original_Node (Expr);
+ E : Node_Id := Original_Node (Expr);
Pre : Node_Id;
-- Start of processing for Accessibility_Level
@@ -777,8 +777,18 @@ package body Sem_Util is
-- We don't handle function calls in prefix notation correctly ???
- when N_Indexed_Component | N_Selected_Component =>
- Pre := Original_Node (Prefix (E));
+ when N_Indexed_Component | N_Selected_Component | N_Slice =>
+ Pre := Prefix (E);
+
+ -- Fetch the original node when the prefix comes from the result
+ -- of expanding a function call since we want to find the level
+ -- of the original source call.
+
+ if not Comes_From_Source (Pre)
+ and then Nkind (Original_Node (Pre)) = N_Function_Call
+ then
+ Pre := Original_Node (Pre);
+ end if;
-- When E is an indexed component or selected component and
-- the current Expr is a function call, we know that we are
@@ -26549,6 +26559,14 @@ package body Sem_Util is
Item_Nam :=
Chars (Original_Node (Pragma_Identifier (Original_Node (Item))));
+ if Item_Nam = Name_Check then
+ -- Pragma "Check" preserves the original pragma name as its first
+ -- argument.
+ Item_Nam :=
+ Chars (Expression (First (Pragma_Argument_Associations
+ (Original_Node (Item)))));
+ end if;
+
else
pragma Assert (Nkind (Item) = N_Aspect_Specification);
Item_Nam := Chars (Identifier (Item));
diff --git a/gcc/ada/sem_warn.ads b/gcc/ada/sem_warn.ads
index 1894f36..6681e54 100644
--- a/gcc/ada/sem_warn.ads
+++ b/gcc/ada/sem_warn.ads
@@ -257,12 +257,9 @@ package Sem_Warn is
----------------------
function Has_Junk_Name (E : Entity_Id) return Boolean;
- -- Return True if the entity name contains any of the following substrings:
- -- discard
- -- dummy
- -- ignore
- -- junk
- -- unused
+ -- Return True if the entity name contains substrings like "junk" or
+ -- "dummy" (see the body for the complete list).
+ --
-- Used to suppress warnings on names matching these patterns. The contents
-- of Name_Buffer and Name_Len are destroyed by this call.
diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
index 5e9cf70..7bdfcbc 100644
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -323,11 +323,7 @@ __gnat_ttyname (int filedes ATTRIBUTE_UNUSED)
|| defined (__QNX__)
# ifdef __MINGW32__
-# if OLD_MINGW
-# include <termios.h>
-# else
-# include <conio.h> /* for getch(), kbhit() */
-# endif
+# include <conio.h> /* for getch(), kbhit() */
# else
# include <termios.h>
# endif
diff --git a/gcc/builtins.def b/gcc/builtins.def
index f023631..109b387 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -114,9 +114,8 @@ along with GCC; see the file COPYING3. If not see
with an argument such as FLOAT32 to produce the enum value for the type. If
we are compiling for the C language with GNU extensions, we enable the name
without the __builtin_ prefix as well as the name with the __builtin_
- prefix. C++ does not enable these names by default because they don't have
- the _Float<N> and _Float<N>X keywords, and a class based library should use
- the __builtin_ names. */
+ prefix. C++ does not enable these names by default because a class based
+ library should use the __builtin_ names. */
#undef DEF_FLOATN_BUILTIN
#define DEF_FLOATN_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 415c4cf..4e99c43 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2022-09-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106656
+ * c-cppbuiltin.cc (c_cpp_builtins): Update value of __cpp_char8_t
+ for C++20.
+
2022-09-23 Marek Polacek <polacek@redhat.com>
PR c++/106784
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index dce3045..cda6910 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -352,13 +352,13 @@ const struct c_common_resword c_common_reswords[] =
{ "_Bool", RID_BOOL, D_CONLY },
{ "_Complex", RID_COMPLEX, 0 },
{ "_Imaginary", RID_IMAGINARY, D_CONLY },
- { "_Float16", RID_FLOAT16, D_CONLY },
- { "_Float32", RID_FLOAT32, D_CONLY },
- { "_Float64", RID_FLOAT64, D_CONLY },
- { "_Float128", RID_FLOAT128, D_CONLY },
- { "_Float32x", RID_FLOAT32X, D_CONLY },
- { "_Float64x", RID_FLOAT64X, D_CONLY },
- { "_Float128x", RID_FLOAT128X, D_CONLY },
+ { "_Float16", RID_FLOAT16, 0 },
+ { "_Float32", RID_FLOAT32, 0 },
+ { "_Float64", RID_FLOAT64, 0 },
+ { "_Float128", RID_FLOAT128, 0 },
+ { "_Float32x", RID_FLOAT32X, 0 },
+ { "_Float64x", RID_FLOAT64X, 0 },
+ { "_Float128x", RID_FLOAT128X, 0 },
{ "_Decimal32", RID_DFLOAT32, D_CONLY },
{ "_Decimal64", RID_DFLOAT64, D_CONLY },
{ "_Decimal128", RID_DFLOAT128, D_CONLY },
@@ -1431,8 +1431,11 @@ shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
== TYPE_PRECISION (TREE_TYPE (arg0)))
&& unsigned0 == unsigned1
&& (unsigned0 || !uns))
- return c_common_signed_or_unsigned_type
- (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ {
+ tree ctype = common_type (TREE_TYPE (arg0), TREE_TYPE (arg1));
+ if (ctype != error_mark_node)
+ return c_common_signed_or_unsigned_type (unsigned0, ctype);
+ }
else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns)
@@ -3204,9 +3207,10 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr,
else if (unsignedp0 == unsignedp1 && real1 == real2
&& TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr)
- && TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (*restype_ptr))
+ && TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (*restype_ptr)
+ && (type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1)))
+ != error_mark_node)
{
- type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
type = c_common_signed_or_unsigned_type (unsignedp0
|| TYPE_UNSIGNED (*restype_ptr),
type);
@@ -4380,11 +4384,18 @@ c_common_nodes_and_builtins (void)
record_builtin_type (RID_DOUBLE, NULL, double_type_node);
record_builtin_type (RID_MAX, "long double", long_double_type_node);
- if (!c_dialect_cxx ())
- for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+ for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
+ {
if (FLOATN_NX_TYPE_NODE (i) != NULL_TREE)
record_builtin_type ((enum rid) (RID_FLOATN_NX_FIRST + i), NULL,
FLOATN_NX_TYPE_NODE (i));
+ }
+
+ /* For C, let float128t_type_node (__float128 in some backends) be the
+ same type as float128_type_node (_Float128), for C++ let those
+ be distinct types that mangle and behave differently. */
+ if (c_dialect_cxx ())
+ float128t_type_node = NULL_TREE;
/* Only supported decimal floating point extension if the target
actually supports underlying modes. */
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 31397d8..50a4691 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1286,6 +1286,7 @@ struct c_omp_directive {
bool simd;
};
+extern const struct c_omp_directive c_omp_directives[];
extern const struct c_omp_directive *c_omp_categorize_directive (const char *,
const char *,
const char *);
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index a1557eb..ca5f500 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1081,6 +1081,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_constexpr=202110L");
cpp_define (pfile, "__cpp_multidimensional_subscript=202110L");
cpp_define (pfile, "__cpp_named_character_escapes=202207L");
+ cpp_define (pfile, "__cpp_static_call_operator=202207L");
}
if (flag_concepts)
{
@@ -1112,7 +1113,7 @@ c_cpp_builtins (cpp_reader *pfile)
if (flag_threadsafe_statics)
cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
if (flag_char8_t)
- cpp_define (pfile, "__cpp_char8_t=201811L");
+ cpp_define (pfile, "__cpp_char8_t=202207L");
#ifndef THREAD_MODEL_SPEC
/* Targets that define THREAD_MODEL_SPEC need to define
__STDCPP_THREADS__ in their config/XXX/XXX-c.c themselves. */
@@ -1246,6 +1247,14 @@ c_cpp_builtins (cpp_reader *pfile)
{
if (FLOATN_NX_TYPE_NODE (i) == NULL_TREE)
continue;
+ if (c_dialect_cxx ()
+ && cxx_dialect > cxx20
+ && !floatn_nx_types[i].extended)
+ {
+ char name[sizeof ("__STDCPP_FLOAT128_T__=1")];
+ sprintf (name, "__STDCPP_FLOAT%d_T__=1", floatn_nx_types[i].n);
+ cpp_define (pfile, name);
+ }
char prefix[20], csuffix[20];
sprintf (prefix, "FLT%d%s", floatn_nx_types[i].n,
floatn_nx_types[i].extended ? "X" : "");
diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc
index 110d029..4d2252f 100644
--- a/gcc/c-family/c-lex.cc
+++ b/gcc/c-family/c-lex.cc
@@ -960,6 +960,10 @@ interpret_float (const cpp_token *token, unsigned int flags,
pedwarn (input_location, OPT_Wpedantic, "non-standard suffix on floating constant");
type = c_common_type_for_mode (mode, 0);
+ /* For Q suffix, prefer float128t_type_node (__float128) type
+ over float128_type_node (_Float128) type if they are distinct. */
+ if (type == float128_type_node && float128t_type_node)
+ type = float128t_type_node;
gcc_assert (type);
}
else if ((flags & (CPP_N_FLOATN | CPP_N_FLOATNX)) != 0)
@@ -979,8 +983,17 @@ interpret_float (const cpp_token *token, unsigned int flags,
error ("unsupported non-standard suffix on floating constant");
return error_mark_node;
}
+ else if (c_dialect_cxx () && !extended)
+ {
+ if (cxx_dialect < cxx23)
+ pedwarn (input_location, OPT_Wpedantic,
+ "%<f%d%> or %<F%d%> suffix on floating constant only "
+ "available with %<-std=c++2b%> or %<-std=gnu++2b%>",
+ n, n);
+ }
else
- pedwarn (input_location, OPT_Wpedantic, "non-standard suffix on floating constant");
+ pedwarn (input_location, OPT_Wpedantic,
+ "non-standard suffix on floating constant");
}
else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
type = long_double_type_node;
@@ -990,7 +1003,10 @@ interpret_float (const cpp_token *token, unsigned int flags,
else
type = double_type_node;
- const_type = excess_precision_type (type);
+ if (c_dialect_cxx ())
+ const_type = NULL_TREE;
+ else
+ const_type = excess_precision_type (type);
if (!const_type)
const_type = type;
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 1b086d8..7a97c40 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -3097,21 +3097,21 @@ c_omp_adjust_map_clauses (tree clauses, bool is_target)
}
}
-static const struct c_omp_directive omp_directives[] = {
+const struct c_omp_directive c_omp_directives[] = {
/* Keep this alphabetically sorted by the first word. Non-null second/third
if any should precede null ones. */
{ "allocate", nullptr, nullptr, PRAGMA_OMP_ALLOCATE,
C_OMP_DIR_DECLARATIVE, false },
- /* { "assume", nullptr, nullptr, PRAGMA_OMP_ASSUME,
- C_OMP_DIR_INFORMATIONAL, false }, */
- /* { "assumes", nullptr, nullptr, PRAGMA_OMP_ASSUMES,
- C_OMP_DIR_INFORMATIONAL, false }, */
+ { "assume", nullptr, nullptr, PRAGMA_OMP_ASSUME,
+ C_OMP_DIR_INFORMATIONAL, false },
+ { "assumes", nullptr, nullptr, PRAGMA_OMP_ASSUMES,
+ C_OMP_DIR_INFORMATIONAL, false },
{ "atomic", nullptr, nullptr, PRAGMA_OMP_ATOMIC,
C_OMP_DIR_CONSTRUCT, false },
{ "barrier", nullptr, nullptr, PRAGMA_OMP_BARRIER,
C_OMP_DIR_STANDALONE, false },
- /* { "begin", "assumes", nullptr, PRAGMA_OMP_BEGIN,
- C_OMP_DIR_INFORMATIONAL, false }, */
+ { "begin", "assumes", nullptr, PRAGMA_OMP_BEGIN,
+ C_OMP_DIR_INFORMATIONAL, false },
/* { "begin", "declare", "target", PRAGMA_OMP_BEGIN,
C_OMP_DIR_DECLARATIVE, false }, */
/* { "begin", "declare", "variant", PRAGMA_OMP_BEGIN,
@@ -3140,9 +3140,9 @@ static const struct c_omp_directive omp_directives[] = {
C_OMP_DIR_CONSTRUCT, false }, */
{ "distribute", nullptr, nullptr, PRAGMA_OMP_DISTRIBUTE,
C_OMP_DIR_CONSTRUCT, true },
- /* { "end", "assumes", nullptr, PRAGMA_OMP_END,
- C_OMP_DIR_INFORMATIONAL, false }, */
- { "end", "declare", "target", PRAGMA_OMP_END_DECLARE_TARGET,
+ { "end", "assumes", nullptr, PRAGMA_OMP_END,
+ C_OMP_DIR_INFORMATIONAL, false },
+ { "end", "declare", "target", PRAGMA_OMP_END,
C_OMP_DIR_DECLARATIVE, false },
/* { "end", "declare", "variant", PRAGMA_OMP_END,
C_OMP_DIR_DECLARATIVE, false }, */
@@ -3224,26 +3224,26 @@ const struct c_omp_directive *
c_omp_categorize_directive (const char *first, const char *second,
const char *third)
{
- const size_t n_omp_directives = ARRAY_SIZE (omp_directives);
+ const size_t n_omp_directives = ARRAY_SIZE (c_omp_directives);
for (size_t i = 0; i < n_omp_directives; i++)
{
- if ((unsigned char) omp_directives[i].first[0]
+ if ((unsigned char) c_omp_directives[i].first[0]
< (unsigned char) first[0])
continue;
- if ((unsigned char) omp_directives[i].first[0]
+ if ((unsigned char) c_omp_directives[i].first[0]
> (unsigned char) first[0])
break;
- if (strcmp (omp_directives[i].first, first))
+ if (strcmp (c_omp_directives[i].first, first))
continue;
- if (!omp_directives[i].second)
- return &omp_directives[i];
- if (!second || strcmp (omp_directives[i].second, second))
+ if (!c_omp_directives[i].second)
+ return &c_omp_directives[i];
+ if (!second || strcmp (c_omp_directives[i].second, second))
continue;
- if (!omp_directives[i].third)
- return &omp_directives[i];
- if (!third || strcmp (omp_directives[i].third, third))
+ if (!c_omp_directives[i].third)
+ return &c_omp_directives[i];
+ if (!third || strcmp (c_omp_directives[i].third, third))
continue;
- return &omp_directives[i];
+ return &c_omp_directives[i];
}
return NULL;
}
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 789719e..b5a4b3c 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1546,14 +1546,16 @@ static const struct omp_pragma_def oacc_pragmas[] = {
};
static const struct omp_pragma_def omp_pragmas[] = {
{ "allocate", PRAGMA_OMP_ALLOCATE },
+ { "assumes", PRAGMA_OMP_ASSUMES },
{ "atomic", PRAGMA_OMP_ATOMIC },
{ "barrier", PRAGMA_OMP_BARRIER },
+ { "begin", PRAGMA_OMP_BEGIN },
{ "cancel", PRAGMA_OMP_CANCEL },
{ "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
{ "critical", PRAGMA_OMP_CRITICAL },
{ "depobj", PRAGMA_OMP_DEPOBJ },
{ "error", PRAGMA_OMP_ERROR },
- { "end", PRAGMA_OMP_END_DECLARE_TARGET },
+ { "end", PRAGMA_OMP_END },
{ "flush", PRAGMA_OMP_FLUSH },
{ "nothing", PRAGMA_OMP_NOTHING },
{ "requires", PRAGMA_OMP_REQUIRES },
@@ -1568,6 +1570,7 @@ static const struct omp_pragma_def omp_pragmas[] = {
{ "threadprivate", PRAGMA_OMP_THREADPRIVATE }
};
static const struct omp_pragma_def omp_pragmas_simd[] = {
+ { "assume", PRAGMA_OMP_ASSUME },
{ "declare", PRAGMA_OMP_DECLARE },
{ "distribute", PRAGMA_OMP_DISTRIBUTE },
{ "for", PRAGMA_OMP_FOR },
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index c894a25..10a4053 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -45,8 +45,11 @@ enum pragma_kind {
/* PRAGMA_OMP__START_ should be equal to the first PRAGMA_OMP_* code. */
PRAGMA_OMP_ALLOCATE,
PRAGMA_OMP__START_ = PRAGMA_OMP_ALLOCATE,
+ PRAGMA_OMP_ASSUME,
+ PRAGMA_OMP_ASSUMES,
PRAGMA_OMP_ATOMIC,
PRAGMA_OMP_BARRIER,
+ PRAGMA_OMP_BEGIN,
PRAGMA_OMP_CANCEL,
PRAGMA_OMP_CANCELLATION_POINT,
PRAGMA_OMP_CRITICAL,
@@ -54,7 +57,7 @@ enum pragma_kind {
PRAGMA_OMP_DEPOBJ,
PRAGMA_OMP_DISTRIBUTE,
PRAGMA_OMP_ERROR,
- PRAGMA_OMP_END_DECLARE_TARGET,
+ PRAGMA_OMP_END,
PRAGMA_OMP_FLUSH,
PRAGMA_OMP_FOR,
PRAGMA_OMP_LOOP,
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 21248d3..4b852b8 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,10 @@
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/106981
+ * c-typeck.cc (c_tree_equal): Only strip NON_LVALUE_EXPRs at the
+ start. For CONSTANT_CLASS_P or CASE_CONVERT: return false if t1 and
+ t2 have different types.
+
2022-09-22 David Malcolm <dmalcolm@redhat.com>
PR c/106830
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index b09c639..740982e 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -156,6 +156,10 @@ static bool undef_nested_function;
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
int current_omp_declare_target_attribute;
+
+/* If non-zero, we are inside of
+ #pragma omp begin assumes ... #pragma omp end assumes region. */
+int current_omp_begin_assumes;
/* Each c_binding structure describes one binding of an identifier to
a decl. All the decls in a scope - irrespective of namespace - are
diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h
index 7bdab47..861abe8 100644
--- a/gcc/c/c-lang.h
+++ b/gcc/c/c-lang.h
@@ -63,5 +63,8 @@ struct GTY(()) language_function {
/* If non-zero, implicit "omp declare target" attribute is added into the
attribute lists. */
extern GTY(()) int current_omp_declare_target_attribute;
+/* Similarly whether we are in between #pragma omp begin assumes and
+ #pragma omp end assumes (and how many times when nested). */
+extern GTY(()) int current_omp_begin_assumes;
#endif /* ! GCC_C_LANG_H */
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index bce79d3..f2498dc 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -71,6 +71,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pretty-print.h"
#include "memmodel.h"
#include "c-family/known-headers.h"
+#include "bitmap.h"
/* We need to walk over decls with incomplete struct/union/enum types
after parsing the whole translation unit.
@@ -1594,10 +1595,13 @@ enum pragma_context { pragma_external, pragma_struct, pragma_param,
static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
-static void c_parser_omp_end_declare_target (c_parser *);
+static void c_parser_omp_begin (c_parser *);
+static void c_parser_omp_end (c_parser *);
static bool c_parser_omp_declare (c_parser *, enum pragma_context);
static void c_parser_omp_requires (c_parser *);
static bool c_parser_omp_error (c_parser *, enum pragma_context);
+static void c_parser_omp_assumption_clauses (c_parser *, bool);
+static void c_parser_omp_assumes (c_parser *);
static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
static void c_parser_oacc_routine (c_parser *, enum pragma_context);
@@ -1678,6 +1682,13 @@ c_parser_translation_unit (c_parser *parser)
"%<#pragma omp end declare target%>");
current_omp_declare_target_attribute = 0;
}
+ if (current_omp_begin_assumes)
+ {
+ if (!errorcount)
+ error ("%<#pragma omp begin assumes%> without corresponding "
+ "%<#pragma omp end assumes%>");
+ current_omp_begin_assumes = 0;
+ }
}
/* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
@@ -12594,8 +12605,12 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
case PRAGMA_OMP_TARGET:
return c_parser_omp_target (parser, context, if_p);
- case PRAGMA_OMP_END_DECLARE_TARGET:
- c_parser_omp_end_declare_target (parser);
+ case PRAGMA_OMP_BEGIN:
+ c_parser_omp_begin (parser);
+ return false;
+
+ case PRAGMA_OMP_END:
+ c_parser_omp_end (parser);
return false;
case PRAGMA_OMP_SCAN:
@@ -12619,13 +12634,26 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
if (context != pragma_external)
{
error_at (c_parser_peek_token (parser)->location,
- "%<#pragma omp requires%> may only be used at file scope");
+ "%<#pragma %s%> may only be used at file scope",
+ "omp requires");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
c_parser_omp_requires (parser);
return false;
+ case PRAGMA_OMP_ASSUMES:
+ if (context != pragma_external)
+ {
+ error_at (c_parser_peek_token (parser)->location,
+ "%<#pragma %s%> may only be used at file scope",
+ "omp assumes");
+ c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+ return false;
+ }
+ c_parser_omp_assumes (parser);
+ return false;
+
case PRAGMA_OMP_NOTHING:
c_parser_omp_nothing (parser);
return false;
@@ -22405,14 +22433,44 @@ c_parser_omp_declare_target (c_parser *parser)
"directive with only %<device_type%> clauses ignored");
}
+/* OpenMP 5.1
+ #pragma omp begin assumes clauses[optseq] new-line */
+
+static void
+c_parser_omp_begin (c_parser *parser)
+{
+ const char *p = "";
+ c_parser_consume_pragma (parser);
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "assumes") == 0)
+ {
+ c_parser_consume_token (parser);
+ c_parser_omp_assumption_clauses (parser, false);
+ current_omp_begin_assumes++;
+ }
+ else
+ {
+ c_parser_error (parser, "expected %<assumes%>");
+ c_parser_skip_to_pragma_eol (parser);
+ }
+}
+
+/* OpenMP 4.0
+ #pragma omp end declare target
+
+ OpenMP 5.1
+ #pragma omp end assumes */
+
static void
-c_parser_omp_end_declare_target (c_parser *parser)
+c_parser_omp_end (c_parser *parser)
{
location_t loc = c_parser_peek_token (parser)->location;
+ const char *p = "";
c_parser_consume_pragma (parser);
- if (c_parser_next_token_is (parser, CPP_NAME)
- && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
- "declare") == 0)
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "declare") == 0)
{
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME)
@@ -22425,22 +22483,30 @@ c_parser_omp_end_declare_target (c_parser *parser)
c_parser_skip_to_pragma_eol (parser);
return;
}
+ c_parser_skip_to_pragma_eol (parser);
+ if (!current_omp_declare_target_attribute)
+ error_at (loc, "%<#pragma omp end declare target%> without "
+ "corresponding %<#pragma omp declare target%>");
+ else
+ current_omp_declare_target_attribute--;
}
- else
+ else if (strcmp (p, "assumes") == 0)
{
- c_parser_error (parser, "expected %<declare%>");
+ c_parser_consume_token (parser);
c_parser_skip_to_pragma_eol (parser);
- return;
+ if (!current_omp_begin_assumes)
+ error_at (loc, "%<#pragma omp end assumes%> without "
+ "corresponding %<#pragma omp begin assumes%>");
+ else
+ current_omp_begin_assumes--;
}
- c_parser_skip_to_pragma_eol (parser);
- if (!current_omp_declare_target_attribute)
- error_at (loc, "%<#pragma omp end declare target%> without corresponding "
- "%<#pragma omp declare target%>");
else
- current_omp_declare_target_attribute--;
+ {
+ c_parser_error (parser, "expected %<declare%> or %<assumes%>");
+ c_parser_skip_to_pragma_eol (parser);
+ }
}
-
/* OpenMP 4.0
#pragma omp declare reduction (reduction-id : typename-list : expression) \
initializer-clause[opt] new-line
@@ -23299,6 +23365,211 @@ c_parser_omp_error (c_parser *parser, enum pragma_context context)
return false;
}
+/* Assumption clauses:
+ OpenMP 5.1
+ absent (directive-name-list)
+ contains (directive-name-list)
+ holds (expression)
+ no_openmp
+ no_openmp_routines
+ no_parallelism */
+
+static void
+c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
+{
+ bool first = true;
+ bool no_openmp = false;
+ bool no_openmp_routines = false;
+ bool no_parallelism = false;
+ bitmap_head absent_head, contains_head;
+
+ bitmap_obstack_initialize (NULL);
+ bitmap_initialize (&absent_head, &bitmap_default_obstack);
+ bitmap_initialize (&contains_head, &bitmap_default_obstack);
+
+ if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
+ error_at (c_parser_peek_token (parser)->location,
+ "expected at least one assumption clause");
+
+ while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+ {
+ if (!first
+ && c_parser_next_token_is (parser, CPP_COMMA)
+ && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
+ c_parser_consume_token (parser);
+
+ first = false;
+
+ if (!c_parser_next_token_is (parser, CPP_NAME))
+ break;
+
+ const char *p
+ = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ location_t cloc = c_parser_peek_token (parser)->location;
+
+ if (!strcmp (p, "no_openmp"))
+ {
+ c_parser_consume_token (parser);
+ if (no_openmp)
+ error_at (cloc, "too many %qs clauses", "no_openmp");
+ no_openmp = true;
+ }
+ else if (!strcmp (p, "no_openmp_routines"))
+ {
+ c_parser_consume_token (parser);
+ if (no_openmp_routines)
+ error_at (cloc, "too many %qs clauses", "no_openmp_routines");
+ no_openmp_routines = true;
+ }
+ else if (!strcmp (p, "no_parallelism"))
+ {
+ c_parser_consume_token (parser);
+ if (no_parallelism)
+ error_at (cloc, "too many %qs clauses", "no_parallelism");
+ no_parallelism = true;
+ }
+ else if (!strcmp (p, "holds"))
+ {
+ c_parser_consume_token (parser);
+ matching_parens parens;
+ if (parens.require_open (parser))
+ {
+ location_t eloc = c_parser_peek_token (parser)->location;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
+ t = c_objc_common_truthvalue_conversion (eloc, t);
+ t = c_fully_fold (t, false, NULL);
+ if (is_assume)
+ {
+ /* FIXME: Emit .ASSUME (t) call here. */
+ (void) t;
+ }
+ parens.skip_until_found_close (parser);
+ }
+ }
+ else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
+ {
+ c_parser_consume_token (parser);
+ matching_parens parens;
+ if (parens.require_open (parser))
+ {
+ do
+ {
+ const char *directive[3] = {};
+ int i;
+ location_t dloc = c_parser_peek_token (parser)->location;
+ for (i = 0; i < 3; i++)
+ {
+ tree id;
+ if (c_parser_peek_nth_token (parser, i + 1)->type
+ == CPP_NAME)
+ id = c_parser_peek_nth_token (parser, i + 1)->value;
+ else if (c_parser_peek_nth_token (parser, i + 1)->keyword
+ != RID_MAX)
+ {
+ enum rid rid
+ = c_parser_peek_nth_token (parser, i + 1)->keyword;
+ id = ridpointers[rid];
+ }
+ else
+ break;
+ directive[i] = IDENTIFIER_POINTER (id);
+ }
+ if (i == 0)
+ error_at (dloc, "expected directive name");
+ else
+ {
+ const struct c_omp_directive *dir
+ = c_omp_categorize_directive (directive[0],
+ directive[1],
+ directive[2]);
+ if (dir == NULL
+ || dir->kind == C_OMP_DIR_DECLARATIVE
+ || dir->kind == C_OMP_DIR_INFORMATIONAL
+ || dir->id == PRAGMA_OMP_END
+ || (!dir->second && directive[1])
+ || (!dir->third && directive[2]))
+ error_at (dloc, "unknown OpenMP directive name in "
+ "%qs clause argument", p);
+ else
+ {
+ int id = dir - c_omp_directives;
+ if (bitmap_bit_p (p[0] == 'a' ? &contains_head
+ : &absent_head, id))
+ error_at (dloc, "%<%s%s%s%s%s%> directive "
+ "mentioned in both %<absent%> and "
+ "%<contains%> clauses",
+ directive[0],
+ directive[1] ? " " : "",
+ directive[1] ? directive[1] : "",
+ directive[2] ? " " : "",
+ directive[2] ? directive[2] : "");
+ else if (!bitmap_set_bit (p[0] == 'a'
+ ? &absent_head
+ : &contains_head, id))
+ error_at (dloc, "%<%s%s%s%s%s%> directive "
+ "mentioned multiple times in %qs "
+ "clauses",
+ directive[0],
+ directive[1] ? " " : "",
+ directive[1] ? directive[1] : "",
+ directive[2] ? " " : "",
+ directive[2] ? directive[2] : "", p);
+ }
+ for (; i; --i)
+ c_parser_consume_token (parser);
+ }
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ c_parser_consume_token (parser);
+ else
+ break;
+ }
+ while (1);
+ parens.skip_until_found_close (parser);
+ }
+ }
+ else if (startswith (p, "ext_"))
+ {
+ warning_at (cloc, 0, "unknown assumption clause %qs", p);
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ matching_parens parens;
+ parens.consume_open (parser);
+ c_parser_balanced_token_sequence (parser);
+ parens.require_close (parser);
+ }
+ }
+ else
+ {
+ c_parser_consume_token (parser);
+ error_at (cloc, "expected assumption clause");
+ break;
+ }
+ }
+ c_parser_skip_to_pragma_eol (parser);
+}
+
+/* OpenMP 5.1
+ #pragma omp assume clauses[optseq] new-line */
+
+static void
+c_parser_omp_assume (c_parser *parser, bool *if_p)
+{
+ c_parser_omp_assumption_clauses (parser, true);
+ add_stmt (c_parser_omp_structured_block (parser, if_p));
+}
+
+/* OpenMP 5.1
+ #pragma omp assumes clauses[optseq] new-line */
+
+static void
+c_parser_omp_assumes (c_parser *parser)
+{
+ c_parser_consume_pragma (parser);
+ c_parser_omp_assumption_clauses (parser, false);
+}
+
/* Main entry point to parsing most OpenMP pragmas. */
static void
@@ -23404,6 +23675,9 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
strcpy (p_name, "#pragma omp");
stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
break;
+ case PRAGMA_OMP_ASSUME:
+ c_parser_omp_assume (parser, if_p);
+ return;
default:
gcc_unreachable ();
}
diff --git a/gcc/cfgcleanup.cc b/gcc/cfgcleanup.cc
index a8b0139..a363e0b 100644
--- a/gcc/cfgcleanup.cc
+++ b/gcc/cfgcleanup.cc
@@ -2599,7 +2599,7 @@ trivially_empty_bb_p (basic_block bb)
return value. Fill in *RET and *USE with the return and use insns
if any found, otherwise NULL. All CLOBBERs are ignored. */
-static bool
+bool
bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
{
*ret = *use = NULL;
diff --git a/gcc/cfgcleanup.h b/gcc/cfgcleanup.h
index a6d882f..f1021ca 100644
--- a/gcc/cfgcleanup.h
+++ b/gcc/cfgcleanup.h
@@ -30,5 +30,6 @@ extern int flow_find_head_matching_sequence (basic_block, basic_block,
extern bool delete_unreachable_blocks (void);
extern void delete_dead_jumptables (void);
extern bool cleanup_cfg (int);
+extern bool bb_is_just_return (basic_block, rtx_insn **, rtx_insn **);
#endif /* GCC_CFGCLEANUP_H */
diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
index a05c338..281a432 100644
--- a/gcc/cfgrtl.cc
+++ b/gcc/cfgrtl.cc
@@ -3901,6 +3901,7 @@ fixup_reorder_chain (void)
/* Now add jumps and labels as needed to match the blocks new
outgoing edges. */
+ bool remove_unreachable_blocks = false;
for (bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; bb ; bb = (basic_block)
bb->aux)
{
@@ -4043,10 +4044,31 @@ fixup_reorder_chain (void)
continue;
}
+ /* If E_FALL->dest is just a return block, then we can emit a
+ return rather than a jump to the return block. */
+ rtx_insn *ret, *use;
+ basic_block dest;
+ if (bb_is_just_return (e_fall->dest, &ret, &use)
+ && ((PATTERN (ret) == simple_return_rtx && targetm.have_simple_return ())
+ || (PATTERN (ret) == ret_rtx && targetm.have_return ())))
+ {
+ ret_label = PATTERN (ret);
+ dest = EXIT_BLOCK_PTR_FOR_FN (cfun);
+
+ /* E_FALL->dest might become unreachable as a result of
+ replacing the jump with a return. So arrange to remove
+ unreachable blocks. */
+ remove_unreachable_blocks = true;
+ }
+ else
+ {
+ dest = e_fall->dest;
+ }
+
/* We got here if we need to add a new jump insn.
Note force_nonfallthru can delete E_FALL and thus we have to
save E_FALL->src prior to the call to force_nonfallthru. */
- nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest, ret_label);
+ nb = force_nonfallthru_and_redirect (e_fall, dest, ret_label);
if (nb)
{
nb->aux = bb->aux;
@@ -4134,6 +4156,12 @@ fixup_reorder_chain (void)
ei_next (&ei2);
}
}
+
+ /* Replacing a jump with a return may have exposed an unreachable
+ block. Conditionally remove them if such transformations were
+ made. */
+ if (remove_unreachable_blocks)
+ delete_unreachable_blocks ();
}
/* Perform sanity checks on the insn chain.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 27ffce3..c1b1215 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3941,6 +3941,9 @@ if test x$with_arch = x ; then
mips*-*-vxworks)
with_arch=mips2
;;
+ nvptx-*)
+ with_arch=sm_30
+ ;;
esac
# Avoid overriding --with-arch-32 and --with-arch-64 values.
@@ -5293,6 +5296,25 @@ case "${target}" in
esac
;;
+ nvptx-*)
+ supported_defaults=arch
+ TM_MULTILIB_CONFIG=$with_arch
+ #TODO 'sm_[...]' list per 'nvptx-sm.def'.
+ case $with_arch in
+ sm_30 )
+ # OK; default.
+ ;;
+ sm_35 | sm_53 | sm_70 | sm_75 | sm_80 )
+ # OK, but we'd like 'sm_30', too.
+ TM_MULTILIB_CONFIG="$TM_MULTILIB_CONFIG sm_30"
+ ;;
+ * )
+ echo "Unknown arch used in --with-arch=$with_arch" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
+
powerpc*-*-* | rs6000-*-*)
supported_defaults="abi cpu cpu_32 cpu_64 float tune tune_32 tune_64 advance_toolchain"
diff --git a/gcc/config/aarch64/aarch64-arches.def b/gcc/config/aarch64/aarch64-arches.def
index 3c2b165..6150448 100644
--- a/gcc/config/aarch64/aarch64-arches.def
+++ b/gcc/config/aarch64/aarch64-arches.def
@@ -41,5 +41,8 @@ AARCH64_ARCH("armv8.7-a", generic, 8_7A, 8, AARCH64_FL_FOR_ARCH8
AARCH64_ARCH("armv8.8-a", generic, 8_8A, 8, AARCH64_FL_FOR_ARCH8_8)
AARCH64_ARCH("armv8-r", generic, 8R , 8, AARCH64_FL_FOR_ARCH8_R)
AARCH64_ARCH("armv9-a", generic, 9A , 9, AARCH64_FL_FOR_ARCH9)
+AARCH64_ARCH("armv9.1-a", generic, 9_1A, 9, AARCH64_FL_FOR_ARCH9_1)
+AARCH64_ARCH("armv9.2-a", generic, 9_2A, 9, AARCH64_FL_FOR_ARCH9_2)
+AARCH64_ARCH("armv9.3-a", generic, 9_3A, 9, AARCH64_FL_FOR_ARCH9_3)
#undef AARCH64_ARCH
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 6f6bb70..f790de1 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -239,6 +239,15 @@
/* Armv8.8-a architecture extensions. */
#define AARCH64_FL_V8_8 (1ULL << 45)
+/* Armv9.1-A. */
+#define AARCH64_FL_V9_1 (1ULL << 46)
+
+/* Armv9.2-A. */
+#define AARCH64_FL_V9_2 (1ULL << 47)
+
+/* Armv9.3-A. */
+#define AARCH64_FL_V9_3 (1ULL << 48)
+
/* Has FP and SIMD. */
#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)
@@ -273,6 +282,12 @@
#define AARCH64_FL_FOR_ARCH9 \
(AARCH64_FL_FOR_ARCH8_5 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_V9 \
| AARCH64_FL_F16)
+#define AARCH64_FL_FOR_ARCH9_1 \
+ (AARCH64_FL_FOR_ARCH9 | AARCH64_FL_FOR_ARCH8_6 | AARCH64_FL_V9_1)
+#define AARCH64_FL_FOR_ARCH9_2 \
+ (AARCH64_FL_FOR_ARCH9_1 | AARCH64_FL_FOR_ARCH8_7 | AARCH64_FL_V9_2)
+#define AARCH64_FL_FOR_ARCH9_3 \
+ (AARCH64_FL_FOR_ARCH9_2 | AARCH64_FL_FOR_ARCH8_8 | AARCH64_FL_V9_3)
/* Macros to test ISA flags. */
@@ -312,6 +327,9 @@
#define AARCH64_ISA_V8_R (aarch64_isa_flags & AARCH64_FL_V8_R)
#define AARCH64_ISA_PAUTH (aarch64_isa_flags & AARCH64_FL_PAUTH)
#define AARCH64_ISA_V9 (aarch64_isa_flags & AARCH64_FL_V9)
+#define AARCH64_ISA_V9_1 (aarch64_isa_flags & AARCH64_FL_V9_1)
+#define AARCH64_ISA_V9_2 (aarch64_isa_flags & AARCH64_FL_V9_2)
+#define AARCH64_ISA_V9_3 (aarch64_isa_flags & AARCH64_FL_V9_3)
#define AARCH64_ISA_MOPS (aarch64_isa_flags & AARCH64_FL_MOPS)
#define AARCH64_ISA_LS64 (aarch64_isa_flags & AARCH64_FL_LS64)
diff --git a/gcc/config/i386/avx512fp16intrin.h b/gcc/config/i386/avx512fp16intrin.h
index 2804151..75f7475 100644
--- a/gcc/config/i386/avx512fp16intrin.h
+++ b/gcc/config/i386/avx512fp16intrin.h
@@ -183,21 +183,21 @@ extern __inline __m128h
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_setzero_ph (void)
{
- return _mm_set1_ph (0.0f);
+ return _mm_set1_ph (0.0f16);
}
extern __inline __m256h
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_setzero_ph (void)
{
- return _mm256_set1_ph (0.0f);
+ return _mm256_set1_ph (0.0f16);
}
extern __inline __m512h
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_setzero_ph (void)
{
- return _mm512_set1_ph (0.0f);
+ return _mm512_set1_ph (0.0f16);
}
extern __inline __m128h
@@ -358,7 +358,8 @@ extern __inline __m128h
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_set_sh (_Float16 __F)
{
- return _mm_set_ph (0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, __F);
+ return _mm_set_ph (0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16,
+ __F);
}
/* Create a vector with element 0 as *P and the rest zero. */
@@ -366,7 +367,7 @@ extern __inline __m128h
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_load_sh (void const *__P)
{
- return _mm_set_ph (0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ return _mm_set_ph (0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16,
*(_Float16 const *) __P);
}
diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
index af2faee..b91aba1 100644
--- a/gcc/config/i386/i386-builtins.cc
+++ b/gcc/config/i386/i386-builtins.cc
@@ -1409,9 +1409,18 @@ ix86_init_builtin_types (void)
lang_hooks.types.register_builtin_type (float80_type_node, "__float80");
/* The __float128 type. The node has already been created as
- _Float128, so we only need to register the __float128 name for
- it. */
- lang_hooks.types.register_builtin_type (float128_type_node, "__float128");
+ _Float128, so for C we only need to register the __float128 name for
+ it. For C++, we create a distinct type which will mangle differently
+ (g) vs. _Float128 (DF128_) and behave backwards compatibly. */
+ if (float128t_type_node == NULL_TREE)
+ {
+ float128t_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (float128t_type_node)
+ = TYPE_PRECISION (float128_type_node);
+ SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node));
+ layout_type (float128t_type_node);
+ }
+ lang_hooks.types.register_builtin_type (float128t_type_node, "__float128");
ix86_register_float16_builtin_type ();
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 5334363..6baff6d 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -19604,6 +19604,119 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
return false;
}
+/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D
+ in terms of a pair of shufps+ shufps/pshufd instructions. */
+static bool
+expand_vec_perm_shufps_shufps (struct expand_vec_perm_d *d)
+{
+ unsigned char perm1[4];
+ machine_mode vmode = d->vmode;
+ bool ok;
+ unsigned i, j, k, count = 0;
+
+ if (d->one_operand_p
+ || (vmode != V4SImode && vmode != V4SFmode))
+ return false;
+
+ if (d->testing_p)
+ return true;
+
+ for (i = 0; i < 4; ++i)
+ count += d->perm[i] > 3 ? 1 : 0;
+
+ gcc_assert (count & 3);
+
+ rtx tmp = gen_reg_rtx (vmode);
+ /* 2 from op0 and 2 from op1. */
+ if (count == 2)
+ {
+ unsigned char perm2[4];
+ for (i = 0, j = 0, k = 2; i < 4; ++i)
+ if (d->perm[i] & 4)
+ {
+ perm1[k++] = d->perm[i];
+ perm2[i] = k - 1;
+ }
+ else
+ {
+ perm1[j++] = d->perm[i];
+ perm2[i] = j - 1;
+ }
+
+ /* shufps. */
+ ok = expand_vselect_vconcat (tmp, d->op0, d->op1,
+ perm1, d->nelt, false);
+ gcc_assert (ok);
+ if (vmode == V4SImode && TARGET_SSE2)
+ /* pshufd. */
+ ok = expand_vselect (d->target, tmp,
+ perm2, d->nelt, false);
+ else
+ {
+ /* shufps. */
+ perm2[2] += 4;
+ perm2[3] += 4;
+ ok = expand_vselect_vconcat (d->target, tmp, tmp,
+ perm2, d->nelt, false);
+ }
+ gcc_assert (ok);
+ }
+ /* 3 from one op and 1 from another. */
+ else
+ {
+ unsigned pair_idx = 8, lone_idx = 8, shift;
+
+ /* Find the lone index. */
+ for (i = 0; i < 4; ++i)
+ if ((d->perm[i] > 3 && count == 1)
+ || (d->perm[i] < 4 && count == 3))
+ lone_idx = i;
+
+ /* When lone_idx is not 0, it must from second op(count == 1). */
+ gcc_assert (count == (lone_idx ? 1 : 3));
+
+ /* Find the pair index that sits in the same half as the lone index. */
+ shift = lone_idx & 2;
+ pair_idx = 1 - lone_idx + 2 * shift;
+
+ /* First permutate lone index and pair index into the same vector as
+ [ lone, lone, pair, pair ]. */
+ perm1[1] = perm1[0]
+ = (count == 3) ? d->perm[lone_idx] : d->perm[lone_idx] - 4;
+ perm1[3] = perm1[2]
+ = (count == 3) ? d->perm[pair_idx] : d->perm[pair_idx] + 4;
+
+ /* Alway put the vector contains lone indx at the first. */
+ if (count == 1)
+ std::swap (d->op0, d->op1);
+
+ /* shufps. */
+ ok = expand_vselect_vconcat (tmp, d->op0, d->op1,
+ perm1, d->nelt, false);
+ gcc_assert (ok);
+
+ /* Refine lone and pair index to original order. */
+ perm1[shift] = lone_idx << 1;
+ perm1[shift + 1] = pair_idx << 1;
+
+ /* Select the remaining 2 elements in another vector. */
+ for (i = 2 - shift; i < 4 - shift; ++i)
+ perm1[i] = lone_idx == 1 ? d->perm[i] + 4 : d->perm[i];
+
+ /* Adjust to original selector. */
+ if (lone_idx > 1)
+ std::swap (tmp, d->op1);
+
+ /* shufps. */
+ ok = expand_vselect_vconcat (d->target, tmp, d->op1,
+ perm1, d->nelt, false);
+
+ gcc_assert (ok);
+ }
+
+ return true;
+}
+
/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D
in terms of a pair of pshuflw + pshufhw instructions. */
@@ -22152,6 +22265,9 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
if (expand_vec_perm_2perm_pblendv (d, true))
return true;
+ if (expand_vec_perm_shufps_shufps (d))
+ return true;
+
/* Try sequences of three instructions. */
if (expand_vec_perm_even_odd_pack (d))
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index ca799da..4386caf 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -22735,7 +22735,10 @@ ix86_mangle_type (const_tree type)
return "DF16_";
case E_TFmode:
/* __float128 is "g". */
- return "g";
+ if (type == float128t_type_node)
+ return "g";
+ /* _Float128 should mangle as "DF128_" done in generic code. */
+ return NULL;
case E_XFmode:
/* "long double" or __float80 is "e". */
return "e";
diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
index 50ae7aa..d510573 100644
--- a/gcc/config/ia64/ia64.cc
+++ b/gcc/config/ia64/ia64.cc
@@ -10466,11 +10466,19 @@ ia64_init_builtins (void)
= build_pointer_type (build_qualified_type
(char_type_node, TYPE_QUAL_CONST));
- (*lang_hooks.types.register_builtin_type) (float128_type_node,
+ if (float128t_type_node == NULL_TREE)
+ {
+ float128t_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (float128t_type_node)
+ = TYPE_PRECISION (float128_type_node);
+ layout_type (float128t_type_node);
+ SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node));
+ }
+ (*lang_hooks.types.register_builtin_type) (float128t_type_node,
"__float128");
/* TFmode support builtins. */
- ftype = build_function_type_list (float128_type_node, NULL_TREE);
+ ftype = build_function_type_list (float128t_type_node, NULL_TREE);
decl = add_builtin_function ("__builtin_infq", ftype,
IA64_BUILTIN_INFQ, BUILT_IN_MD,
NULL, NULL_TREE);
@@ -10481,7 +10489,7 @@ ia64_init_builtins (void)
NULL, NULL_TREE);
ia64_builtins[IA64_BUILTIN_HUGE_VALQ] = decl;
- ftype = build_function_type_list (float128_type_node,
+ ftype = build_function_type_list (float128t_type_node,
const_string_type,
NULL_TREE);
decl = add_builtin_function ("__builtin_nanq", ftype,
@@ -10496,8 +10504,8 @@ ia64_init_builtins (void)
TREE_READONLY (decl) = 1;
ia64_builtins[IA64_BUILTIN_NANSQ] = decl;
- ftype = build_function_type_list (float128_type_node,
- float128_type_node,
+ ftype = build_function_type_list (float128t_type_node,
+ float128t_type_node,
NULL_TREE);
decl = add_builtin_function ("__builtin_fabsq", ftype,
IA64_BUILTIN_FABSQ, BUILT_IN_MD,
@@ -10505,9 +10513,9 @@ ia64_init_builtins (void)
TREE_READONLY (decl) = 1;
ia64_builtins[IA64_BUILTIN_FABSQ] = decl;
- ftype = build_function_type_list (float128_type_node,
- float128_type_node,
- float128_type_node,
+ ftype = build_function_type_list (float128t_type_node,
+ float128t_type_node,
+ float128t_type_node,
NULL_TREE);
decl = add_builtin_function ("__builtin_copysignq", ftype,
IA64_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
diff --git a/gcc/config/nvptx/gen-multilib-matches.sh b/gcc/config/nvptx/gen-multilib-matches.sh
new file mode 100755
index 0000000..9a5878e
--- /dev/null
+++ b/gcc/config/nvptx/gen-multilib-matches.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# Print nvptx 'MULTILIB_MATCHES'
+
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+set -e
+
+nvptx_sm_def="$1/nvptx-sm.def"
+multilib_options_isa_default=$2
+multilib_options_isa_list=$3
+
+sms=$(grep ^NVPTX_SM $nvptx_sm_def | sed 's/.*(//;s/,.*//')
+
+# Every variant in 'sms' has to either be remapped to the default variant
+# ('.', which is always built), or does get built as non-default variant
+# ('misa=sm_SM'; thus not remapped), or has to be remapped to the "next lower"
+# variant that does get built.
+
+# The "lowest" variant has to be built.
+sm_next_lower=INVALID
+
+for sm in $sms; do
+ if [ x"sm_$sm" = x"$multilib_options_isa_default" ]; then
+ sm_map=.
+ elif expr " $multilib_options_isa_list " : ".* sm_$sm " > /dev/null; then
+ sm_map=
+ else
+ sm_map=$sm_next_lower
+ fi
+
+ if [ x"$sm_map" = x ]; then
+ sm_next_lower=$sm
+ else
+ # Output format as required for 'MULTILIB_MATCHES'.
+ if [ x"$sm_map" = x. ]; then
+ echo ".=misa?sm_$sm"
+ else
+ echo "misa?sm_$sm_map=misa?sm_$sm"
+ fi
+
+ sm_next_lower=$sm_map
+ fi
+done
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 49cc681..2fe120b 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -334,6 +334,10 @@ nvptx_option_override (void)
{
init_machine_status = nvptx_init_machine_status;
+ /* Via nvptx 'OPTION_DEFAULT_SPECS', '-misa' always appears on the command
+ line. */
+ gcc_checking_assert (OPTION_SET_P (ptx_isa_option));
+
handle_ptx_version_option ();
/* Set toplevel_reorder, unless explicitly disabled. We need
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index dc9cad1..0afc83b 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -27,6 +27,14 @@
/* Run-time Target. */
+/* Use '--with-arch' for default '-misa'. */
+#define OPTION_DEFAULT_SPECS \
+ { "arch", "%{!misa=*:-misa=%(VALUE)}" }, \
+
+/* Assembler supports '-v' option; handle similar to
+ '../../gcc.cc:asm_options', 'HAVE_GNU_AS'. */
+#define ASM_SPEC "%{v}"
+
#define STARTFILE_SPEC "%{mmainkernel:crt0.o}"
#define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins ()
diff --git a/gcc/config/nvptx/nvptx.opt b/gcc/config/nvptx/nvptx.opt
index c5a5668..71d3b68 100644
--- a/gcc/config/nvptx/nvptx.opt
+++ b/gcc/config/nvptx/nvptx.opt
@@ -53,7 +53,7 @@ Target Mask(GOMP)
Generate code for OpenMP offloading: enables -msoft-stack and -muniform-simt.
misa=
-Target RejectNegative ToLower Joined Enum(ptx_isa) Var(ptx_isa_option) Init(PTX_ISA_SM30)
+Target RejectNegative ToLower Joined Enum(ptx_isa) Var(ptx_isa_option)
Specify the PTX ISA target architecture to use.
march=
diff --git a/gcc/config/nvptx/t-nvptx b/gcc/config/nvptx/t-nvptx
index 2b68149..9c5cbda 100644
--- a/gcc/config/nvptx/t-nvptx
+++ b/gcc/config/nvptx/t-nvptx
@@ -31,4 +31,33 @@ s-nvptx-gen-opt: $(srcdir)/config/nvptx/nvptx-sm.def \
tmp-nvptx-gen.opt $(srcdir)/config/nvptx/nvptx-gen.opt
$(STAMP) s-nvptx-gen-opt
-MULTILIB_OPTIONS = mgomp mptx=3.1
+
+# Multilib setup.
+
+MULTILIB_OPTIONS =
+MULTILIB_MATCHES =
+MULTILIB_EXCEPTIONS =
+
+MULTILIB_OPTIONS += mgomp
+
+multilib_options_isa_list := $(TM_MULTILIB_CONFIG)
+multilib_options_isa_default := $(word 1,$(multilib_options_isa_list))
+multilib_options_misa_list := $(addprefix misa=,$(multilib_options_isa_list))
+# Add the requested '-misa' variants as a multilib option ('misa=VAR1/misa=VAR2/misa=VAR3' etc.):
+empty :=
+space := $(empty) $(empty)
+MULTILIB_OPTIONS += $(subst $(space),/,$(multilib_options_misa_list))
+# ..., and remap '-misa' variants as appropriate:
+multilib_matches := $(shell $(srcdir)/config/nvptx/gen-multilib-matches.sh $(srcdir)/config/nvptx $(multilib_options_isa_default) "$(multilib_options_isa_list)")
+MULTILIB_MATCHES += $(multilib_matches)
+# ..., and don't actually build what's the default '-misa':
+MULTILIB_EXCEPTIONS += *misa=$(multilib_options_isa_default)*
+
+MULTILIB_OPTIONS += mptx=3.1
+# Filter out invalid '-misa'/'-mptx=3.1' combinations; per 'nvptx-sm.def',
+# 'nvptx.opt:ptx_version', 'nvptx.cc:first_ptx_version_supporting_sm'
+# (that is, '-mptx=3.1' only for sm_30, sm_35 variants):
+MULTILIB_EXCEPTIONS += $(foreach misa,$(filter-out %=sm_30 %=sm_35,$(multilib_options_misa_list)),*$(misa)/mptx=3.1)
+# ..., and special care has to be taken if '-mptx=3.1' is invalid for the
+# default variant:
+MULTILIB_EXCEPTIONS += $(if $(filter-out sm_30 sm_35,$(multilib_options_isa_default)),mgomp/mptx=3.1 mptx=3.1)
diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 3ce729c..90ab39d 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -733,7 +733,22 @@ rs6000_init_builtins (void)
if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
ieee128_float_type_node = long_double_type_node;
else
- ieee128_float_type_node = float128_type_node;
+ {
+ /* For C we only need to register the __ieee128 name for
+ it. For C++, we create a distinct type which will mangle
+ differently (u9__ieee128) vs. _Float128 (DF128_) and behave
+ backwards compatibly. */
+ if (float128t_type_node == NULL_TREE)
+ {
+ float128t_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (float128t_type_node)
+ = TYPE_PRECISION (float128_type_node);
+ layout_type (float128t_type_node);
+ SET_TYPE_MODE (float128t_type_node,
+ TYPE_MODE (float128_type_node));
+ }
+ ieee128_float_type_node = float128t_type_node;
+ }
t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST);
lang_hooks.types.register_builtin_type (ieee128_float_type_node,
"__ieee128");
diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index ca9cc42..5660946 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -808,6 +808,7 @@ static inline bool
is_float128_p (tree t)
{
return (t == float128_type_node
+ || (t && t == float128t_type_node)
|| (TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
&& t == long_double_type_node));
diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc
index 80a2e0d..f575e69 100644
--- a/gcc/config/rs6000/rs6000-logue.cc
+++ b/gcc/config/rs6000/rs6000-logue.cc
@@ -4920,7 +4920,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
a REG_CFA_DEF_CFA note, but that's OK; A duplicate is
discarded by dwarf2cfi.cc/dwarf2out.cc, and in any case would
be harmless if emitted. */
- if (frame_pointer_needed)
+ if (frame_pointer_needed_indeed)
{
insn = get_last_insn ();
add_reg_note (insn, REG_CFA_DEF_CFA,
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 5f347e9..bbe21ea 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -20272,7 +20272,11 @@ rs6000_mangle_type (const_tree type)
if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IBM_P (TYPE_MODE (type)))
return "g";
- if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IEEE_P (TYPE_MODE (type)))
+ if (SCALAR_FLOAT_TYPE_P (type)
+ && FLOAT128_IEEE_P (TYPE_MODE (type))
+ /* _Float128 should mangle as DF128_ (done in generic code)
+ rather than u9__ieee128 (used for __ieee128 and __float128). */
+ && type != float128_type_node)
return "u9__ieee128";
if (type == vector_pair_type_node)
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index a0d33d2..0171705 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -1475,7 +1475,7 @@
[(match_operand:VEC_L 0 "vlogical_operand")
(match_operand:VEC_L 1 "vlogical_operand")
(match_operand:QI 2 "reg_or_short_operand")]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
{
rtx bitshift = operands[2];
rtx shift;
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 3ae586c..9861913 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -3648,7 +3648,7 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = 0;
return true;
case SET: {
- rtx dest = SET_DEST (x);
+ rtx dst = SET_DEST (x);
rtx src = SET_SRC (x);
switch (GET_CODE (src))
@@ -3669,7 +3669,6 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
slightly more expensive than a normal load. */
*total = COSTS_N_INSNS (1) + 2;
- rtx dst = SET_DEST (src);
rtx then = XEXP (src, 1);
rtx els = XEXP (src, 2);
@@ -3696,25 +3695,25 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
break;
}
- switch (GET_CODE (dest))
+ switch (GET_CODE (dst))
{
case SUBREG:
- if (!REG_P (SUBREG_REG (dest)))
+ if (!REG_P (SUBREG_REG (dst)))
*total += rtx_cost (SUBREG_REG (src), VOIDmode, SET, 0, speed);
/* fallthrough */
case REG:
/* If this is a VR -> VR copy, count the number of
registers. */
- if (VECTOR_MODE_P (GET_MODE (dest)) && REG_P (src))
+ if (VECTOR_MODE_P (GET_MODE (dst)) && REG_P (src))
{
- int nregs = s390_hard_regno_nregs (VR0_REGNUM, GET_MODE (dest));
+ int nregs = s390_hard_regno_nregs (VR0_REGNUM, GET_MODE (dst));
*total = COSTS_N_INSNS (nregs);
}
/* Same for GPRs. */
else if (REG_P (src))
{
int nregs
- = s390_hard_regno_nregs (GPR0_REGNUM, GET_MODE (dest));
+ = s390_hard_regno_nregs (GPR0_REGNUM, GET_MODE (dst));
*total = COSTS_N_INSNS (nregs);
}
else
@@ -3722,7 +3721,7 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total += rtx_cost (src, mode, SET, 1, speed);
return true;
case MEM: {
- rtx address = XEXP (dest, 0);
+ rtx address = XEXP (dst, 0);
rtx tmp;
HOST_WIDE_INT tmp2;
if (s390_loadrelative_operand_p (address, &tmp, &tmp2))
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b9b2729..ca5015e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,28 @@
+2022-09-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106656
+ * typeck2.cc (array_string_literal_compatible_p): Allow
+ initializing arrays of char or unsigned char by a UTF-8 string literal.
+
+2022-09-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106784
+ * method.cc (is_convertible_helper): New.
+ (is_convertible): Use it.
+ (is_nothrow_convertible): Likewise.
+
+2022-09-26 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107033
+ * module.cc (trees_in::decl_value): In the MK_partial case for
+ a variable template partial specialization, pass decl_p=true to
+ add_mergeable_specialization, and set spec to the VAR_DECL not
+ the TEMPLATE_DECL.
+ * pt.cc (add_mergeable_specialization): For a variable template
+ partial specialization, set the TREE_TYPE of the new
+ DECL_TEMPLATE_SPECIALIZATIONS node to the TREE_TYPE of the
+ VAR_DECL not the VAR_DECL itself.
+
2022-09-23 Marek Polacek <polacek@redhat.com>
PR c++/106784
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 7e9289f..fc86b74 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -1541,6 +1541,22 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
|| (underlying_type && same_type_p (to, underlying_type)))
&& next_conversion (conv)->rank <= cr_promotion)
conv->rank = cr_promotion;
+
+ /* A prvalue of floating-point type can be converted to a prvalue of
+ another floating-point type with a greater or equal conversion
+ rank ([conv.rank]). A prvalue of standard floating-point type can
+ be converted to a prvalue of another standard floating-point type.
+ For backwards compatibility with handling __float128 and other
+ non-standard floating point types, allow all implicit floating
+ point conversions if neither type is extended floating-point
+ type and if at least one of them is, fail if they have unordered
+ conversion rank or from has higher conversion rank. */
+ if (fcode == REAL_TYPE
+ && tcode == REAL_TYPE
+ && (extended_float_type_p (from)
+ || extended_float_type_p (to))
+ && cp_compare_floating_point_conversion_ranks (from, to) >= 2)
+ conv->bad_p = true;
}
else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
&& vector_types_convertible_p (from, to, false))
@@ -5842,6 +5858,21 @@ build_conditional_expr (const op_location_t &loc,
/* In this case, there is always a common type. */
result_type = type_after_usual_arithmetic_conversions (arg2_type,
arg3_type);
+ if (result_type == error_mark_node
+ && TREE_CODE (arg2_type) == REAL_TYPE
+ && TREE_CODE (arg3_type) == REAL_TYPE
+ && (extended_float_type_p (arg2_type)
+ || extended_float_type_p (arg3_type))
+ && cp_compare_floating_point_conversion_ranks (arg2_type,
+ arg3_type) == 3)
+ {
+ if (complain & tf_error)
+ error_at (loc, "operands to %<?:%> of types %qT and %qT "
+ "have unordered conversion rank",
+ arg2_type, arg3_type);
+ return error_mark_node;
+ }
+
if (complain & tf_warning)
do_warn_double_promotion (result_type, arg2_type, arg3_type,
"implicit conversion from %qH to %qI to "
@@ -7906,6 +7937,27 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
"direct-initialization",
totype, TREE_TYPE (expr));
+ if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+ && TREE_CODE (totype) == REAL_TYPE
+ && (extended_float_type_p (TREE_TYPE (expr))
+ || extended_float_type_p (totype)))
+ switch (cp_compare_floating_point_conversion_ranks (TREE_TYPE (expr),
+ totype))
+ {
+ case 2:
+ pedwarn (loc, 0, "converting to %qH from %qI with greater "
+ "conversion rank", totype, TREE_TYPE (expr));
+ complained = true;
+ break;
+ case 3:
+ pedwarn (loc, 0, "converting to %qH from %qI with unordered "
+ "conversion ranks", totype, TREE_TYPE (expr));
+ complained = true;
+ break;
+ default:
+ break;
+ }
+
for (; t ; t = next_conversion (t))
{
if (t->kind == ck_user && t->cand->reason)
@@ -8531,7 +8583,8 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
if (TREE_CODE (arg_type) == REAL_TYPE
&& (TYPE_PRECISION (arg_type)
< TYPE_PRECISION (double_type_node))
- && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type)))
+ && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type))
+ && !extended_float_type_p (arg_type))
{
if ((complain & tf_warning)
&& warn_double_promotion && !c_inhibit_evaluation_warnings)
@@ -11719,6 +11772,81 @@ compare_ics (conversion *ics1, conversion *ics2)
return 1;
}
+ {
+ /* A conversion in either direction between floating-point type FP1 and
+ floating-point type FP2 is better than a conversion in the same
+ direction between FP1 and arithmetic type T3 if
+ - the floating-point conversion rank of FP1 is equal to the rank of
+ FP2, and
+ - T3 is not a floating-point type, or T3 is a floating-point type
+ whose rank is not equal to the rank of FP1, or the floating-point
+ conversion subrank of FP2 is greater than the subrank of T3. */
+ tree fp1 = from_type1;
+ tree fp2 = to_type1;
+ tree fp3 = from_type2;
+ tree t3 = to_type2;
+ int ret = 1;
+ if (TYPE_MAIN_VARIANT (fp2) == TYPE_MAIN_VARIANT (t3))
+ {
+ std::swap (fp1, fp2);
+ std::swap (fp3, t3);
+ }
+ if (TYPE_MAIN_VARIANT (fp1) == TYPE_MAIN_VARIANT (fp3)
+ && TREE_CODE (fp1) == REAL_TYPE
+ /* Only apply this rule if at least one of the 3 types is
+ extended floating-point type, otherwise keep them as
+ before for compatibility reasons with types like __float128.
+ float, double and long double alone have different conversion
+ ranks and so when just those 3 types are involved, this
+ rule doesn't trigger. */
+ && (extended_float_type_p (fp1)
+ || (TREE_CODE (fp2) == REAL_TYPE && extended_float_type_p (fp2))
+ || (TREE_CODE (t3) == REAL_TYPE && extended_float_type_p (t3))))
+ {
+ if (TREE_CODE (fp2) != REAL_TYPE)
+ {
+ ret = -ret;
+ std::swap (fp2, t3);
+ }
+ if (TREE_CODE (fp2) == REAL_TYPE)
+ {
+ /* cp_compare_floating_point_conversion_ranks returns -1, 0 or 1
+ if the conversion rank is equal (-1 or 1 if the subrank is
+ different). */
+ if (IN_RANGE (cp_compare_floating_point_conversion_ranks (fp1,
+ fp2),
+ -1, 1))
+ {
+ /* Conversion ranks of FP1 and FP2 are equal. */
+ if (TREE_CODE (t3) != REAL_TYPE
+ || !IN_RANGE (cp_compare_floating_point_conversion_ranks
+ (fp1, t3),
+ -1, 1))
+ /* FP1 <-> FP2 conversion is better. */
+ return ret;
+ int c = cp_compare_floating_point_conversion_ranks (fp2, t3);
+ gcc_assert (IN_RANGE (c, -1, 1));
+ if (c == 1)
+ /* Conversion subrank of FP2 is greater than subrank of T3.
+ FP1 <-> FP2 conversion is better. */
+ return ret;
+ else if (c == -1)
+ /* Conversion subrank of FP2 is less than subrank of T3.
+ FP1 <-> T3 conversion is better. */
+ return -ret;
+ }
+ else if (TREE_CODE (t3) == REAL_TYPE
+ && IN_RANGE (cp_compare_floating_point_conversion_ranks
+ (fp1, t3),
+ -1, 1))
+ /* Conversion ranks of FP1 and FP2 are not equal, conversion
+ ranks of FP1 and T3 are equal.
+ FP1 <-> T3 conversion is better. */
+ return -ret;
+ }
+ }
+ }
+
if (TYPE_PTR_P (from_type1)
&& TYPE_PTR_P (from_type2)
&& TYPE_PTR_P (to_type1)
@@ -12133,10 +12261,14 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
len = cand1->num_convs;
if (len != cand2->num_convs)
{
- int static_1 = DECL_STATIC_FUNCTION_P (cand1->fn);
- int static_2 = DECL_STATIC_FUNCTION_P (cand2->fn);
+ int static_1 = (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (cand1->fn));
+ int static_2 = (TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (cand2->fn));
- if (DECL_CONSTRUCTOR_P (cand1->fn)
+ if (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_CONSTRUCTOR_P (cand1->fn)
&& is_list_ctor (cand1->fn) != is_list_ctor (cand2->fn))
/* We're comparing a near-match list constructor and a near-match
non-list constructor. Just treat them as unordered. */
@@ -12145,9 +12277,20 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
gcc_assert (static_1 != static_2);
if (static_1)
- off2 = 1;
+ {
+ /* C++23 [over.best.ics.general] says:
+ When the parameter is the implicit object parameter of a static
+ member function, the implicit conversion sequence is a standard
+ conversion sequence that is neither better nor worse than any
+ other standard conversion sequence. */
+ if (CONVERSION_RANK (cand2->convs[0]) >= cr_user)
+ winner = 1;
+ off2 = 1;
+ }
else
{
+ if (CONVERSION_RANK (cand1->convs[0]) >= cr_user)
+ winner = -1;
off1 = 1;
--len;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e4d8920..99b486b8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -504,6 +504,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
OVL_NESTED_P (in OVERLOAD)
DECL_MODULE_EXPORT_P (in _DECL)
PACK_EXPANSION_FORCE_EXTRA_ARGS_P (in *_PACK_EXPANSION)
+ LAMBDA_EXPR_STATIC_P (in LAMBDA_EXPR)
4: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
CALL_EXPR, or FIELD_DECL).
@@ -1490,6 +1491,10 @@ enum cp_lambda_default_capture_mode_type {
#define LAMBDA_EXPR_CAPTURE_OPTIMIZED(NODE) \
TREE_LANG_FLAG_2 (LAMBDA_EXPR_CHECK (NODE))
+/* Predicate tracking whether the lambda was declared 'static'. */
+#define LAMBDA_EXPR_STATIC_P(NODE) \
+ TREE_LANG_FLAG_3 (LAMBDA_EXPR_CHECK (NODE))
+
/* True if this TREE_LIST in LAMBDA_EXPR_CAPTURE_LIST is for an explicit
capture. */
#define LAMBDA_CAPTURE_EXPLICIT_P(NODE) \
@@ -1834,6 +1839,10 @@ struct GTY(()) omp_declare_target_attr {
bool attr_syntax;
};
+struct GTY(()) omp_begin_assumes_data {
+ bool attr_syntax;
+};
+
/* Global state. */
struct GTY(()) saved_scope {
@@ -1881,6 +1890,7 @@ struct GTY(()) saved_scope {
hash_map<tree, tree> *GTY((skip)) x_local_specializations;
vec<omp_declare_target_attr, va_gc> *omp_declare_target_attribute;
+ vec<omp_begin_assumes_data, va_gc> *omp_begin_assumes;
struct saved_scope *prev;
};
@@ -7946,6 +7956,7 @@ extern tree require_complete_type (tree,
extern tree complete_type (tree);
extern tree complete_type_or_else (tree, tree);
extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t);
+extern int cp_compare_floating_point_conversion_ranks (tree, tree);
inline bool type_unknown_p (const_tree);
enum { ce_derived, ce_type, ce_normal, ce_exact };
extern bool comp_except_specs (const_tree, const_tree, int);
@@ -8688,6 +8699,18 @@ struct push_access_scope_guard
}
};
+/* True if TYPE is an extended floating-point type. */
+
+inline bool
+extended_float_type_p (tree type)
+{
+ type = TYPE_MAIN_VARIANT (type);
+ for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i)
+ if (type == FLOATN_TYPE_NODE (i))
+ return true;
+ return false;
+}
+
#if CHECKING_P
namespace selftest {
extern void run_cp_tests (void);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 80467c1..fb85564 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -12095,12 +12095,7 @@ grokdeclarator (const cp_declarator *declarator,
}
if (declspecs->conflicting_specifiers_p)
- {
- error_at (min_location (declspecs->locations[ds_typedef],
- declspecs->locations[ds_storage_class]),
- "conflicting specifiers in declaration of %qs", name);
- return error_mark_node;
- }
+ return error_mark_node;
/* Extract the basic type from the decl-specifier-seq. */
type = declspecs->type;
@@ -15305,8 +15300,25 @@ grok_op_properties (tree decl, bool complain)
an enumeration, or a reference to an enumeration. 13.4.0.6 */
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
{
+ if (operator_code == CALL_EXPR)
+ {
+ if (! DECL_STATIC_FUNCTION_P (decl))
+ {
+ error_at (loc, "%qD must be a member function", decl);
+ return false;
+ }
+ if (cxx_dialect < cxx23
+ /* For lambdas we diagnose static lambda specifier elsewhere. */
+ && ! LAMBDA_FUNCTION_P (decl)
+ /* For instantiations, we have diagnosed this already. */
+ && ! DECL_USE_TEMPLATE (decl))
+ pedwarn (loc, OPT_Wc__23_extensions, "%qD may be a static member "
+ "function only with %<-std=c++23%> or %<-std=gnu++23%>", decl);
+ /* There are no further restrictions on the arguments to an
+ overloaded "operator ()". */
+ return true;
+ }
if (operator_code == TYPE_EXPR
- || operator_code == CALL_EXPR
|| operator_code == COMPONENT_REF
|| operator_code == ARRAY_REF
|| operator_code == NOP_EXPR)
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 94181e7..0389f35 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -1692,7 +1692,13 @@ dump_lambda_function (cxx_pretty_printer *pp,
{
/* A lambda's signature is essentially its "type". */
dump_type (pp, DECL_CONTEXT (fn), flags);
- if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST))
+ if (TREE_CODE (TREE_TYPE (fn)) == FUNCTION_TYPE)
+ {
+ pp->padding = pp_before;
+ pp_c_ws_string (pp, "static");
+ }
+ else if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn)))
+ & TYPE_QUAL_CONST))
{
pp->padding = pp_before;
pp_c_ws_string (pp, "mutable");
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 3ee1fe9..e9d5d4d 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1099,7 +1099,9 @@ maybe_add_lambda_conv_op (tree type)
tree optype = TREE_TYPE (callop);
tree fn_result = TREE_TYPE (optype);
- tree thisarg = build_int_cst (TREE_TYPE (DECL_ARGUMENTS (callop)), 0);
+ tree thisarg = NULL_TREE;
+ if (TREE_CODE (optype) == METHOD_TYPE)
+ thisarg = build_int_cst (TREE_TYPE (DECL_ARGUMENTS (callop)), 0);
if (generic_lambda_p)
{
++processing_template_decl;
@@ -1109,18 +1111,25 @@ maybe_add_lambda_conv_op (tree type)
return expression for a deduced return call op to allow for simple
implementation of the conversion operator. */
- tree instance = cp_build_fold_indirect_ref (thisarg);
- tree objfn = lookup_template_function (DECL_NAME (callop),
- DECL_TI_ARGS (callop));
- objfn = build_min (COMPONENT_REF, NULL_TREE,
- instance, objfn, NULL_TREE);
- int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
+ tree objfn;
+ int nargs = list_length (DECL_ARGUMENTS (callop));
+ if (thisarg)
+ {
+ tree instance = cp_build_fold_indirect_ref (thisarg);
+ objfn = lookup_template_function (DECL_NAME (callop),
+ DECL_TI_ARGS (callop));
+ objfn = build_min (COMPONENT_REF, NULL_TREE,
+ instance, objfn, NULL_TREE);
+ --nargs;
+ call = prepare_op_call (objfn, nargs);
+ }
+ else
+ objfn = callop;
- call = prepare_op_call (objfn, nargs);
if (type_uses_auto (fn_result))
decltype_call = prepare_op_call (objfn, nargs);
}
- else
+ else if (thisarg)
{
direct_argvec = make_tree_vector ();
direct_argvec->quick_push (thisarg);
@@ -1135,9 +1144,11 @@ maybe_add_lambda_conv_op (tree type)
tree fn_args = NULL_TREE;
{
int ix = 0;
- tree src = DECL_CHAIN (DECL_ARGUMENTS (callop));
+ tree src = FUNCTION_FIRST_USER_PARM (callop);
tree tgt = NULL;
+ if (!thisarg && !decltype_call)
+ src = NULL_TREE;
while (src)
{
tree new_node = copy_node (src);
@@ -1160,12 +1171,15 @@ maybe_add_lambda_conv_op (tree type)
if (generic_lambda_p)
{
tree a = tgt;
- if (DECL_PACK_P (tgt))
+ if (thisarg)
{
- a = make_pack_expansion (a);
- PACK_EXPANSION_LOCAL_P (a) = true;
+ if (DECL_PACK_P (tgt))
+ {
+ a = make_pack_expansion (a);
+ PACK_EXPANSION_LOCAL_P (a) = true;
+ }
+ CALL_EXPR_ARG (call, ix) = a;
}
- CALL_EXPR_ARG (call, ix) = a;
if (decltype_call)
{
@@ -1193,7 +1207,7 @@ maybe_add_lambda_conv_op (tree type)
tf_warning_or_error);
}
}
- else
+ else if (thisarg)
{
/* Don't warn on deprecated or unavailable lambda declarations, unless
the lambda is actually called. */
@@ -1203,10 +1217,14 @@ maybe_add_lambda_conv_op (tree type)
direct_argvec->address ());
}
- CALL_FROM_THUNK_P (call) = 1;
- SET_EXPR_LOCATION (call, UNKNOWN_LOCATION);
+ if (thisarg)
+ {
+ CALL_FROM_THUNK_P (call) = 1;
+ SET_EXPR_LOCATION (call, UNKNOWN_LOCATION);
+ }
- tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop));
+ tree stattype
+ = build_function_type (fn_result, FUNCTION_FIRST_USER_PARMTYPE (callop));
stattype = (cp_build_type_attribute_variant
(stattype, TYPE_ATTRIBUTES (optype)));
if (flag_noexcept_type
@@ -1249,6 +1267,41 @@ maybe_add_lambda_conv_op (tree type)
add_method (type, fn, false);
+ if (thisarg == NULL_TREE)
+ {
+ /* For static lambda, just return operator(). */
+ if (nested)
+ push_function_context ();
+ else
+ /* Still increment function_depth so that we don't GC in the
+ middle of an expression. */
+ ++function_depth;
+
+ /* Generate the body of the conversion op. */
+
+ start_preparsed_function (convfn, NULL_TREE,
+ SF_PRE_PARSED | SF_INCLASS_INLINE);
+ tree body = begin_function_body ();
+ tree compound_stmt = begin_compound_stmt (0);
+
+ /* decl_needed_p needs to see that it's used. */
+ TREE_USED (callop) = 1;
+ finish_return_stmt (decay_conversion (callop, tf_warning_or_error));
+
+ finish_compound_stmt (compound_stmt);
+ finish_function_body (body);
+
+ fn = finish_function (/*inline_p=*/true);
+ if (!generic_lambda_p)
+ expand_or_defer_fn (fn);
+
+ if (nested)
+ pop_function_context ();
+ else
+ --function_depth;
+ return;
+ }
+
/* Generic thunk code fails for varargs; we'll complain in mark_used if
the conversion op is used. */
if (varargs_function_p (callop))
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 75388e9..00d283f 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -2648,63 +2648,24 @@ write_builtin_type (tree type)
write_string ("Dd");
else if (type == dfloat128_type_node || type == fallback_dfloat128_type)
write_string ("De");
+ else if (type == float16_type_node)
+ write_string ("DF16_");
+ else if (type == float32_type_node)
+ write_string ("DF32_");
+ else if (type == float64_type_node)
+ write_string ("DF64_");
+ else if (type == float128_type_node)
+ write_string ("DF128_");
+ else if (type == float32x_type_node)
+ write_string ("DF32x");
+ else if (type == float64x_type_node)
+ write_string ("DF64x");
+ else if (type == float128x_type_node)
+ write_string ("DF128x");
else
gcc_unreachable ();
break;
- case FIXED_POINT_TYPE:
- write_string ("DF");
- if (GET_MODE_IBIT (TYPE_MODE (type)) > 0)
- write_unsigned_number (GET_MODE_IBIT (TYPE_MODE (type)));
- if (type == fract_type_node
- || type == sat_fract_type_node
- || type == accum_type_node
- || type == sat_accum_type_node)
- write_char ('i');
- else if (type == unsigned_fract_type_node
- || type == sat_unsigned_fract_type_node
- || type == unsigned_accum_type_node
- || type == sat_unsigned_accum_type_node)
- write_char ('j');
- else if (type == short_fract_type_node
- || type == sat_short_fract_type_node
- || type == short_accum_type_node
- || type == sat_short_accum_type_node)
- write_char ('s');
- else if (type == unsigned_short_fract_type_node
- || type == sat_unsigned_short_fract_type_node
- || type == unsigned_short_accum_type_node
- || type == sat_unsigned_short_accum_type_node)
- write_char ('t');
- else if (type == long_fract_type_node
- || type == sat_long_fract_type_node
- || type == long_accum_type_node
- || type == sat_long_accum_type_node)
- write_char ('l');
- else if (type == unsigned_long_fract_type_node
- || type == sat_unsigned_long_fract_type_node
- || type == unsigned_long_accum_type_node
- || type == sat_unsigned_long_accum_type_node)
- write_char ('m');
- else if (type == long_long_fract_type_node
- || type == sat_long_long_fract_type_node
- || type == long_long_accum_type_node
- || type == sat_long_long_accum_type_node)
- write_char ('x');
- else if (type == unsigned_long_long_fract_type_node
- || type == sat_unsigned_long_long_fract_type_node
- || type == unsigned_long_long_accum_type_node
- || type == sat_unsigned_long_long_accum_type_node)
- write_char ('y');
- else
- sorry ("mangling unknown fixed point type");
- write_unsigned_number (GET_MODE_FBIT (TYPE_MODE (type)));
- if (TYPE_SATURATING (type))
- write_char ('s');
- else
- write_char ('n');
- break;
-
default:
gcc_unreachable ();
}
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index c35a59f..9f917f1 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -2236,6 +2236,19 @@ ref_xes_from_temporary (tree to, tree from, bool direct_init_p)
return ref_conv_binds_directly (to, val, direct_init_p).is_false ();
}
+/* Worker for is_{,nothrow_}convertible. Attempt to perform an implicit
+ conversion from FROM to TO and return the result. */
+
+static tree
+is_convertible_helper (tree from, tree to)
+{
+ if (VOID_TYPE_P (from) && VOID_TYPE_P (to))
+ return integer_one_node;
+ cp_unevaluated u;
+ tree expr = build_stub_object (from);
+ return perform_implicit_conversion (to, expr, tf_none);
+}
+
/* Return true if FROM can be converted to TO using implicit conversions,
or both FROM and TO are possibly cv-qualified void. NB: This doesn't
implement the "Access checks are performed as if from a context unrelated
@@ -2244,10 +2257,7 @@ ref_xes_from_temporary (tree to, tree from, bool direct_init_p)
bool
is_convertible (tree from, tree to)
{
- if (VOID_TYPE_P (from) && VOID_TYPE_P (to))
- return true;
- tree expr = build_stub_object (from);
- expr = perform_implicit_conversion (to, expr, tf_none);
+ tree expr = is_convertible_helper (from, to);
if (expr == error_mark_node)
return false;
return !!expr;
@@ -2258,10 +2268,7 @@ is_convertible (tree from, tree to)
bool
is_nothrow_convertible (tree from, tree to)
{
- if (VOID_TYPE_P (from) && VOID_TYPE_P (to))
- return true;
- tree expr = build_stub_object (from);
- expr = perform_implicit_conversion (to, expr, tf_none);
+ tree expr = is_convertible_helper (from, to);
if (expr == NULL_TREE || expr == error_mark_node)
return false;
return expr_noexcept_p (expr, tf_none);
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index f23832c..7496df5 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -8185,13 +8185,18 @@ trees_in::decl_value ()
/* Set the TEMPLATE_DECL's type. */
TREE_TYPE (decl) = TREE_TYPE (inner);
- if (mk & MK_template_mask
- || mk == MK_partial)
+ /* Add to specialization tables now that constraints etc are
+ added. */
+ if (mk == MK_partial)
{
- /* Add to specialization tables now that constraints etc are
- added. */
- bool is_type = mk == MK_partial || !(mk & MK_tmpl_decl_mask);
-
+ bool is_type = TREE_CODE (inner) == TYPE_DECL;
+ spec.spec = is_type ? type : inner;
+ add_mergeable_specialization (!is_type, false,
+ &spec, decl, spec_flags);
+ }
+ else if (mk & MK_template_mask)
+ {
+ bool is_type = !(mk & MK_tmpl_decl_mask);
spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl;
add_mergeable_specialization (!is_type,
!is_type && mk & MK_tmpl_alias_mask,
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index bb83d1c..d501178 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "cp-name-hint.h"
#include "memmodel.h"
#include "c-family/known-headers.h"
+#include "bitmap.h"
/* The lexer. */
@@ -1129,6 +1130,7 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword)
case RID_UNSIGNED:
case RID_FLOAT:
case RID_DOUBLE:
+ CASE_RID_FLOATN_NX:
case RID_VOID:
/* CV qualifiers. */
case RID_CONST:
@@ -1994,7 +1996,7 @@ enum
constexpr. */
CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8,
/* When parsing a decl-specifier-seq, only allow mutable, constexpr or
- for C++20 consteval. */
+ for C++20 consteval or for C++23 static. */
CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10,
/* When parsing a decl-specifier-seq, allow missing typename. */
CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20,
@@ -11728,9 +11730,18 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
{
LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
quals = TYPE_UNQUALIFIED;
- if (lambda_specs.conflicting_specifiers_p)
+ }
+ else if (lambda_specs.storage_class == sc_static)
+ {
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
+ || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr))
error_at (lambda_specs.locations[ds_storage_class],
- "duplicate %<mutable%>");
+ "%<static%> lambda specifier with lambda capture");
+ else
+ {
+ LAMBDA_EXPR_STATIC_P (lambda_expr) = 1;
+ quals = TYPE_UNQUALIFIED;
+ }
}
tx_qual = cp_parser_tx_qualifier_opt (parser);
@@ -11817,6 +11828,12 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
if (lambda_specs.locations[ds_consteval])
return_type_specs.locations[ds_consteval]
= lambda_specs.locations[ds_consteval];
+ if (LAMBDA_EXPR_STATIC_P (lambda_expr))
+ {
+ return_type_specs.storage_class = sc_static;
+ return_type_specs.locations[ds_storage_class]
+ = lambda_specs.locations[ds_storage_class];
+ }
p = obstack_alloc (&declarator_obstack, 0);
@@ -11840,8 +11857,9 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
{
DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
DECL_ARTIFICIAL (fco) = 1;
- /* Give the object parameter a different name. */
- DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
+ if (!LAMBDA_EXPR_STATIC_P (lambda_expr))
+ /* Give the object parameter a different name. */
+ DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
DECL_SET_LAMBDA_FUNCTION (fco, true);
}
if (template_param_list)
@@ -15730,6 +15748,13 @@ cp_parser_decomposition_declaration (cp_parser *parser,
return decl;
}
+/* Names of storage classes. */
+
+static const char *const
+cp_storage_class_name[] = {
+ "", "auto", "register", "static", "extern", "mutable"
+};
+
/* Parse a decl-specifier-seq.
decl-specifier-seq:
@@ -15951,8 +15976,18 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
may as well commit at this point. */
cp_parser_commit_to_tentative_parse (parser);
- if (decl_specs->storage_class != sc_none)
- decl_specs->conflicting_specifiers_p = true;
+ if (decl_specs->storage_class != sc_none)
+ {
+ if (decl_specs->conflicting_specifiers_p)
+ break;
+ gcc_rich_location richloc (token->location);
+ location_t oloc = decl_specs->locations[ds_storage_class];
+ richloc.add_location_if_nearby (oloc);
+ error_at (&richloc,
+ "%<typedef%> specifier conflicts with %qs",
+ cp_storage_class_name[decl_specs->storage_class]);
+ decl_specs->conflicting_specifiers_p = true;
+ }
break;
/* storage-class-specifier:
@@ -16018,8 +16053,15 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
&& token->keyword != RID_MUTABLE
&& token->keyword != RID_CONSTEXPR
&& token->keyword != RID_CONSTEVAL)
- error_at (token->location, "%qD invalid in lambda",
- ridpointers[token->keyword]);
+ {
+ if (token->keyword != RID_STATIC)
+ error_at (token->location, "%qD invalid in lambda",
+ ridpointers[token->keyword]);
+ else if (cxx_dialect < cxx23)
+ pedwarn (token->location, OPT_Wc__23_extensions,
+ "%qD only valid in lambda with %<-std=c++23%> or "
+ "%<-std=gnu++23%>", ridpointers[token->keyword]);
+ }
if (ds != ds_last)
set_and_check_decl_spec_loc (decl_specs, ds, token);
@@ -19716,6 +19758,14 @@ cp_parser_simple_type_specifier (cp_parser* parser,
case RID_DOUBLE:
type = double_type_node;
break;
+ CASE_RID_FLOATN_NX:
+ type = FLOATN_NX_TYPE_NODE (token->keyword - RID_FLOATN_NX_FIRST);
+ if (type == NULL_TREE)
+ error ("%<_Float%d%s%> is not supported on this target",
+ floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].n,
+ floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].extended
+ ? "x" : "");
+ break;
case RID_VOID:
type = void_type_node;
break;
@@ -32836,26 +32886,6 @@ cp_parser_set_storage_class (cp_parser *parser,
{
cp_storage_class storage_class;
- if (parser->in_unbraced_linkage_specification_p)
- {
- error_at (token->location, "invalid use of %qD in linkage specification",
- ridpointers[keyword]);
- return;
- }
- else if (decl_specs->storage_class != sc_none)
- {
- decl_specs->conflicting_specifiers_p = true;
- return;
- }
-
- if ((keyword == RID_EXTERN || keyword == RID_STATIC)
- && decl_spec_seq_has_spec_p (decl_specs, ds_thread)
- && decl_specs->gnu_thread_keyword_p)
- {
- pedwarn (decl_specs->locations[ds_thread], 0,
- "%<__thread%> before %qD", ridpointers[keyword]);
- }
-
switch (keyword)
{
case RID_AUTO:
@@ -32876,6 +32906,38 @@ cp_parser_set_storage_class (cp_parser *parser,
default:
gcc_unreachable ();
}
+
+ if (parser->in_unbraced_linkage_specification_p)
+ {
+ error_at (token->location, "invalid use of %qD in linkage specification",
+ ridpointers[keyword]);
+ return;
+ }
+ else if (decl_specs->storage_class != sc_none)
+ {
+ if (decl_specs->conflicting_specifiers_p)
+ return;
+ gcc_rich_location richloc (token->location);
+ richloc.add_location_if_nearby (decl_specs->locations[ds_storage_class]);
+ if (decl_specs->storage_class == storage_class)
+ error_at (&richloc, "duplicate %qD specifier", ridpointers[keyword]);
+ else
+ error_at (&richloc,
+ "%qD specifier conflicts with %qs",
+ ridpointers[keyword],
+ cp_storage_class_name[decl_specs->storage_class]);
+ decl_specs->conflicting_specifiers_p = true;
+ return;
+ }
+
+ if ((keyword == RID_EXTERN || keyword == RID_STATIC)
+ && decl_spec_seq_has_spec_p (decl_specs, ds_thread)
+ && decl_specs->gnu_thread_keyword_p)
+ {
+ pedwarn (decl_specs->locations[ds_thread], 0,
+ "%<__thread%> before %qD", ridpointers[keyword]);
+ }
+
decl_specs->storage_class = storage_class;
set_and_check_decl_spec_loc (decl_specs, ds_storage_class, token);
@@ -32883,8 +32945,16 @@ cp_parser_set_storage_class (cp_parser *parser,
specifier. If there is a typedef specifier present then set
conflicting_specifiers_p which will trigger an error later
on in grokdeclarator. */
- if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef))
- decl_specs->conflicting_specifiers_p = true;
+ if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
+ && !decl_specs->conflicting_specifiers_p)
+ {
+ gcc_rich_location richloc (token->location);
+ richloc.add_location_if_nearby (decl_specs->locations[ds_typedef]);
+ error_at (&richloc,
+ "%qD specifier conflicts with %<typedef%>",
+ ridpointers[keyword]);
+ decl_specs->conflicting_specifiers_p = true;
+ }
}
/* Update the DECL_SPECS to reflect the TYPE_SPEC. If TYPE_DEFINITION_P
@@ -46018,6 +46088,218 @@ cp_parser_omp_context_selector_specification (cp_parser *parser,
return nreverse (ret);
}
+/* Assumption clauses:
+ OpenMP 5.1
+ absent (directive-name-list)
+ contains (directive-name-list)
+ holds (expression)
+ no_openmp
+ no_openmp_routines
+ no_parallelism */
+
+static void
+cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
+ bool is_assume)
+{
+ bool first = true;
+ bool no_openmp = false;
+ bool no_openmp_routines = false;
+ bool no_parallelism = false;
+ bitmap_head absent_head, contains_head;
+
+ bitmap_obstack_initialize (NULL);
+ bitmap_initialize (&absent_head, &bitmap_default_obstack);
+ bitmap_initialize (&contains_head, &bitmap_default_obstack);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "expected at least one assumption clause");
+
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
+ {
+ /* For now only in C++ attributes, do it always for OpenMP 5.1. */
+ if ((!first || parser->lexer->in_omp_attribute_pragma)
+ && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ cp_lexer_consume_token (parser->lexer);
+
+ first = false;
+
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ break;
+
+ const char *p
+ = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
+ location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
+
+ if (!strcmp (p, "no_openmp"))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (no_openmp)
+ error_at (cloc, "too many %qs clauses", "no_openmp");
+ no_openmp = true;
+ }
+ else if (!strcmp (p, "no_openmp_routines"))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (no_openmp_routines)
+ error_at (cloc, "too many %qs clauses", "no_openmp_routines");
+ no_openmp_routines = true;
+ }
+ else if (!strcmp (p, "no_parallelism"))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ if (no_parallelism)
+ error_at (cloc, "too many %qs clauses", "no_parallelism");
+ no_parallelism = true;
+ }
+ else if (!strcmp (p, "holds"))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ if (parens.require_open (parser))
+ {
+ tree t = cp_parser_assignment_expression (parser);
+ if (!type_dependent_expression_p (t))
+ t = contextual_conv_bool (t, tf_warning_or_error);
+ if (is_assume)
+ {
+ /* FIXME: Emit .ASSUME (t) call here. */
+ (void) t;
+ }
+ if (!parens.require_close (parser))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
+ }
+ else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ if (parens.require_open (parser))
+ {
+ do
+ {
+ const char *directive[3] = {};
+ int i;
+ location_t dloc
+ = cp_lexer_peek_token (parser->lexer)->location;
+ for (i = 0; i < 3; i++)
+ {
+ tree id;
+ if (cp_lexer_nth_token_is (parser->lexer, i + 1, CPP_NAME))
+ id = cp_lexer_peek_nth_token (parser->lexer,
+ i + 1)->u.value;
+ else if (cp_lexer_nth_token_is (parser->lexer, i + 1,
+ CPP_KEYWORD))
+ {
+ enum rid rid
+ = cp_lexer_peek_nth_token (parser->lexer,
+ i + 1)->keyword;
+ id = ridpointers[rid];
+ }
+ else
+ break;
+ directive[i] = IDENTIFIER_POINTER (id);
+ }
+ if (i == 0)
+ error_at (dloc, "expected directive name");
+ else
+ {
+ const struct c_omp_directive *dir
+ = c_omp_categorize_directive (directive[0],
+ directive[1],
+ directive[2]);
+ if (dir == NULL
+ || dir->kind == C_OMP_DIR_DECLARATIVE
+ || dir->kind == C_OMP_DIR_INFORMATIONAL
+ || dir->id == PRAGMA_OMP_END
+ || (!dir->second && directive[1])
+ || (!dir->third && directive[2]))
+ error_at (dloc, "unknown OpenMP directive name in "
+ "%qs clause argument", p);
+ else
+ {
+ int id = dir - c_omp_directives;
+ if (bitmap_bit_p (p[0] == 'a' ? &contains_head
+ : &absent_head, id))
+ error_at (dloc, "%<%s%s%s%s%s%> directive "
+ "mentioned in both %<absent%> and "
+ "%<contains%> clauses",
+ directive[0],
+ directive[1] ? " " : "",
+ directive[1] ? directive[1] : "",
+ directive[2] ? " " : "",
+ directive[2] ? directive[2] : "");
+ else if (!bitmap_set_bit (p[0] == 'a'
+ ? &absent_head
+ : &contains_head, id))
+ error_at (dloc, "%<%s%s%s%s%s%> directive "
+ "mentioned multiple times in %qs "
+ "clauses",
+ directive[0],
+ directive[1] ? " " : "",
+ directive[1] ? directive[1] : "",
+ directive[2] ? " " : "",
+ directive[2] ? directive[2] : "", p);
+ }
+ for (; i; --i)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ break;
+ }
+ while (1);
+ if (!parens.require_close (parser))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
+ }
+ else if (startswith (p, "ext_"))
+ {
+ warning_at (cloc, 0, "unknown assumption clause %qs", p);
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1;
+ n; --n)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ {
+ cp_lexer_consume_token (parser->lexer);
+ error_at (cloc, "expected assumption clause");
+ break;
+ }
+ }
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+}
+
+/* OpenMP 5.1
+ # pragma omp assume clauses[optseq] new-line */
+
+static void
+cp_parser_omp_assume (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
+{
+ cp_parser_omp_assumption_clauses (parser, pragma_tok, true);
+ add_stmt (cp_parser_omp_structured_block (parser, if_p));
+}
+
+/* OpenMP 5.1
+ # pragma omp assumes clauses[optseq] new-line */
+
+static bool
+cp_parser_omp_assumes (cp_parser *parser, cp_token *pragma_tok)
+{
+ cp_parser_omp_assumption_clauses (parser, pragma_tok, false);
+ return false;
+}
+
/* Finalize #pragma omp declare variant after a fndecl has been parsed, and put
that into "omp declare variant base" attribute. */
@@ -46467,8 +46749,41 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
"directive with only %<device_type%> clauses ignored");
}
+/* OpenMP 5.1
+ #pragma omp begin assumes clauses[optseq] new-line */
+
static void
-cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok)
+cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok)
+{
+ const char *p = "";
+ bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+ if (strcmp (p, "assumes") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_assumption_clauses (parser, pragma_tok, false);
+ struct omp_begin_assumes_data a = { in_omp_attribute_pragma };
+ vec_safe_push (scope_chain->omp_begin_assumes, a);
+ }
+ else
+ {
+ cp_parser_error (parser, "expected %<assumes%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ }
+}
+
+/* OpenMP 4.0:
+ # pragma omp end declare target new-line
+
+ OpenMP 5.1:
+ # pragma omp end assumes new-line */
+
+static void
+cp_parser_omp_end (cp_parser *parser, cp_token *pragma_tok)
{
const char *p = "";
bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
@@ -46494,33 +46809,58 @@ cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok)
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return;
}
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ if (!vec_safe_length (scope_chain->omp_declare_target_attribute))
+ error_at (pragma_tok->location,
+ "%<#pragma omp end declare target%> without corresponding "
+ "%<#pragma omp declare target%>");
+ else
+ {
+ omp_declare_target_attr
+ a = scope_chain->omp_declare_target_attribute->pop ();
+ if (a.attr_syntax != in_omp_attribute_pragma)
+ {
+ if (a.attr_syntax)
+ error_at (pragma_tok->location,
+ "%<declare target%> in attribute syntax terminated "
+ "with %<end declare target%> in pragma syntax");
+ else
+ error_at (pragma_tok->location,
+ "%<declare target%> in pragma syntax terminated "
+ "with %<end declare target%> in attribute syntax");
+ }
+ }
}
- else
+ else if (strcmp (p, "assumes") == 0)
{
- cp_parser_error (parser, "expected %<declare%>");
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- return;
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+ if (!vec_safe_length (scope_chain->omp_begin_assumes))
+ error_at (pragma_tok->location,
+ "%<#pragma omp end assumes%> without corresponding "
+ "%<#pragma omp begin assumes%>");
+ else
+ {
+ omp_begin_assumes_data
+ a = scope_chain->omp_begin_assumes->pop ();
+ if (a.attr_syntax != in_omp_attribute_pragma)
+ {
+ if (a.attr_syntax)
+ error_at (pragma_tok->location,
+ "%<begin assumes%> in attribute syntax terminated "
+ "with %<end assumes%> in pragma syntax");
+ else
+ error_at (pragma_tok->location,
+ "%<begin assumes%> in pragma syntax terminated "
+ "with %<end assumes%> in attribute syntax");
+ }
+ }
}
- cp_parser_require_pragma_eol (parser, pragma_tok);
- if (!vec_safe_length (scope_chain->omp_declare_target_attribute))
- error_at (pragma_tok->location,
- "%<#pragma omp end declare target%> without corresponding "
- "%<#pragma omp declare target%>");
else
{
- omp_declare_target_attr
- a = scope_chain->omp_declare_target_attribute->pop ();
- if (a.attr_syntax != in_omp_attribute_pragma)
- {
- if (a.attr_syntax)
- error_at (pragma_tok->location,
- "%<declare target%> in attribute syntax terminated "
- "with %<end declare target%> in pragma syntax");
- else
- error_at (pragma_tok->location,
- "%<declare target%> in pragma syntax terminated "
- "with %<end declare target%> in attribute syntax");
- }
+ cp_parser_error (parser, "expected %<declare%> or %<assumes%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return;
}
}
@@ -47803,6 +48143,9 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL,
if_p);
break;
+ case PRAGMA_OMP_ASSUME:
+ cp_parser_omp_assume (parser, pragma_tok, if_p);
+ return;
default:
gcc_unreachable ();
}
@@ -48406,6 +48749,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
case PRAGMA_OACC_LOOP:
case PRAGMA_OACC_PARALLEL:
case PRAGMA_OACC_SERIAL:
+ case PRAGMA_OMP_ASSUME:
case PRAGMA_OMP_ATOMIC:
case PRAGMA_OMP_CRITICAL:
case PRAGMA_OMP_DISTRIBUTE:
@@ -48440,6 +48784,17 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
}
return cp_parser_omp_requires (parser, pragma_tok);
+ case PRAGMA_OMP_ASSUMES:
+ if (context != pragma_external)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp assumes%> may only be used at file or "
+ "namespace scope");
+ ret = true;
+ break;
+ }
+ return cp_parser_omp_assumes (parser, pragma_tok);
+
case PRAGMA_OMP_NOTHING:
cp_parser_omp_nothing (parser, pragma_tok);
return false;
@@ -48463,8 +48818,12 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
pop_omp_privatization_clauses (stmt);
return ret;
- case PRAGMA_OMP_END_DECLARE_TARGET:
- cp_parser_omp_end_declare_target (parser, pragma_tok);
+ case PRAGMA_OMP_BEGIN:
+ cp_parser_omp_begin (parser, pragma_tok);
+ return false;
+
+ case PRAGMA_OMP_END:
+ cp_parser_omp_end (parser, pragma_tok);
return false;
case PRAGMA_OMP_SCAN:
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index db4e808..1c1e573 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -11945,6 +11945,7 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
auto o3 = make_temp_override (current_target_pragma, NULL_TREE);
auto o4 = make_temp_override (scope_chain->omp_declare_target_attribute,
NULL);
+ auto o5 = make_temp_override (scope_chain->omp_begin_assumes, NULL);
cplus_decl_attributes (decl_p, late_attrs, attr_flags);
@@ -31010,7 +31011,7 @@ add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt,
/* A partial specialization. */
tree cons = tree_cons (elt->args, decl,
DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl));
- TREE_TYPE (cons) = elt->spec;
+ TREE_TYPE (cons) = decl_p ? TREE_TYPE (elt->spec) : elt->spec;
DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl) = cons;
}
}
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 92fc795..e8cd505 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -3363,6 +3363,13 @@ finish_translation_unit (void)
"%<#pragma omp end declare target%>");
vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0);
}
+ if (vec_safe_length (scope_chain->omp_begin_assumes))
+ {
+ if (!errorcount)
+ error ("%<#pragma omp begin assumes%> without corresponding "
+ "%<#pragma omp end assumes%>");
+ vec_safe_truncate (scope_chain->omp_begin_assumes, 0);
+ }
}
/* Finish a template type parameter, specified as AGGR IDENTIFIER.
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 22d834d..4854b98 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -267,6 +267,133 @@ merge_type_attributes_from (tree type, tree other_type)
return cp_build_type_attribute_variant (type, attrs);
}
+/* Compare floating point conversion ranks and subranks of T1 and T2
+ types. If T1 and T2 have unordered conversion ranks, return 3.
+ If T1 has greater conversion rank than T2, return 2.
+ If T2 has greater conversion rank than T1, return -2.
+ If T1 has equal conversion rank as T2, return -1, 0 or 1 depending
+ on if T1 has smaller, equal or greater conversion subrank than
+ T2. */
+
+int
+cp_compare_floating_point_conversion_ranks (tree t1, tree t2)
+{
+ tree mv1 = TYPE_MAIN_VARIANT (t1);
+ tree mv2 = TYPE_MAIN_VARIANT (t2);
+ int extended1 = 0;
+ int extended2 = 0;
+
+ if (mv1 == mv2)
+ return 0;
+
+ for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i)
+ {
+ if (mv1 == FLOATN_NX_TYPE_NODE (i))
+ extended1 = i + 1;
+ if (mv2 == FLOATN_NX_TYPE_NODE (i))
+ extended2 = i + 1;
+ }
+ if (extended2 && !extended1)
+ {
+ int ret = cp_compare_floating_point_conversion_ranks (t2, t1);
+ return ret == 3 ? 3 : -ret;
+ }
+
+ const struct real_format *fmt1 = REAL_MODE_FORMAT (TYPE_MODE (t1));
+ const struct real_format *fmt2 = REAL_MODE_FORMAT (TYPE_MODE (t2));
+ gcc_assert (fmt1->b == 2 && fmt2->b == 2);
+ /* For {ibm,mips}_extended_format formats, the type has variable
+ precision up to ~2150 bits when the first double is around maximum
+ representable double and second double is subnormal minimum.
+ So, e.g. for __ibm128 vs. std::float128_t, they have unordered
+ ranks. */
+ int p1 = (MODE_COMPOSITE_P (TYPE_MODE (t1))
+ ? fmt1->emax - fmt1->emin + fmt1->p - 1 : fmt1->p);
+ int p2 = (MODE_COMPOSITE_P (TYPE_MODE (t2))
+ ? fmt2->emax - fmt2->emin + fmt2->p - 1 : fmt2->p);
+ /* The rank of a floating point type T is greater than the rank of
+ any floating-point type whose set of values is a proper subset
+ of the set of values of T. */
+ if ((p1 > p2 && fmt1->emax >= fmt2->emax)
+ || (p1 == p2 && fmt1->emax > fmt2->emax))
+ return 2;
+ if ((p1 < p2 && fmt1->emax <= fmt2->emax)
+ || (p1 == p2 && fmt1->emax < fmt2->emax))
+ return -2;
+ if ((p1 > p2 && fmt1->emax < fmt2->emax)
+ || (p1 < p2 && fmt1->emax > fmt2->emax))
+ return 3;
+ if (!extended1 && !extended2)
+ {
+ /* The rank of long double is greater than the rank of double, which
+ is greater than the rank of float. */
+ if (t1 == long_double_type_node)
+ return 2;
+ else if (t2 == long_double_type_node)
+ return -2;
+ if (t1 == double_type_node)
+ return 2;
+ else if (t2 == double_type_node)
+ return -2;
+ if (t1 == float_type_node)
+ return 2;
+ else if (t2 == float_type_node)
+ return -2;
+ return 0;
+ }
+ /* Two extended floating-point types with the same set of values have equal
+ ranks. */
+ if (extended1 && extended2)
+ {
+ if ((extended1 <= NUM_FLOATN_TYPES) == (extended2 <= NUM_FLOATN_TYPES))
+ {
+ /* Prefer higher extendedN value. */
+ if (extended1 > extended2)
+ return 1;
+ else if (extended1 < extended2)
+ return -1;
+ else
+ return 0;
+ }
+ else if (extended1 <= NUM_FLOATN_TYPES)
+ /* Prefer _FloatN type over _FloatMx type. */
+ return 1;
+ else if (extended2 <= NUM_FLOATN_TYPES)
+ return -1;
+ else
+ return 0;
+ }
+
+ /* gcc_assert (extended1 && !extended2); */
+ tree *p;
+ int cnt = 0;
+ for (p = &float_type_node; p <= &long_double_type_node; ++p)
+ {
+ const struct real_format *fmt3 = REAL_MODE_FORMAT (TYPE_MODE (*p));
+ gcc_assert (fmt3->b == 2);
+ int p3 = (MODE_COMPOSITE_P (TYPE_MODE (*p))
+ ? fmt3->emax - fmt3->emin + fmt3->p - 1 : fmt3->p);
+ if (p1 == p3 && fmt1->emax == fmt3->emax)
+ ++cnt;
+ }
+ /* An extended floating-point type with the same set of values
+ as exactly one cv-unqualified standard floating-point type
+ has a rank equal to the rank of that standard floating-point
+ type.
+
+ An extended floating-point type with the same set of values
+ as more than one cv-unqualified standard floating-point type
+ has a rank equal to the rank of double.
+
+ Thus, if the latter is true and t2 is long double, t2
+ has higher rank. */
+ if (cnt > 1 && mv2 == long_double_type_node)
+ return -2;
+ /* Otherwise, they have equal rank, but extended types
+ (other than std::bfloat16_t) have higher subrank. */
+ return 1;
+}
+
/* Return the common type for two arithmetic types T1 and T2 under the
usual arithmetic conversions. The default conversions have already
been applied, and enumerated types converted to their compatible
@@ -337,6 +464,23 @@ cp_common_type (tree t1, tree t2)
if (code2 == REAL_TYPE && code1 != REAL_TYPE)
return build_type_attribute_variant (t2, attributes);
+ if (code1 == REAL_TYPE
+ && (extended_float_type_p (t1) || extended_float_type_p (t2)))
+ {
+ tree mv1 = TYPE_MAIN_VARIANT (t1);
+ tree mv2 = TYPE_MAIN_VARIANT (t2);
+ if (mv1 == mv2)
+ return build_type_attribute_variant (t1, attributes);
+
+ int cmpret = cp_compare_floating_point_conversion_ranks (mv1, mv2);
+ if (cmpret == 3)
+ return error_mark_node;
+ else if (cmpret >= 0)
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return build_type_attribute_variant (t2, attributes);
+ }
+
/* Both real or both integers; use the one with greater precision. */
if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
return build_type_attribute_variant (t1, attributes);
@@ -5037,7 +5181,20 @@ cp_build_binary_op (const op_location_t &location,
= targetm.invalid_binary_op (code, type0, type1)))
{
if (complain & tf_error)
- error (invalid_op_diag);
+ {
+ if (code0 == REAL_TYPE
+ && code1 == REAL_TYPE
+ && (extended_float_type_p (type0)
+ || extended_float_type_p (type1))
+ && cp_compare_floating_point_conversion_ranks (type0,
+ type1) == 3)
+ {
+ rich_location richloc (line_table, location);
+ binary_op_error (&richloc, code, type0, type1);
+ }
+ else
+ error (invalid_op_diag);
+ }
return error_mark_node;
}
@@ -5907,6 +6064,19 @@ cp_build_binary_op (const op_location_t &location,
&& (shorten || common || short_compare))
{
result_type = cp_common_type (type0, type1);
+ if (result_type == error_mark_node
+ && code0 == REAL_TYPE
+ && code1 == REAL_TYPE
+ && (extended_float_type_p (type0) || extended_float_type_p (type1))
+ && cp_compare_floating_point_conversion_ranks (type0, type1) == 3)
+ {
+ if (complain & tf_error)
+ {
+ rich_location richloc (line_table, location);
+ binary_op_error (&richloc, code, type0, type1);
+ }
+ return error_mark_node;
+ }
if (complain & tf_warning)
{
do_warn_double_promotion (result_type, type0, type1,
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index 75fd0e2..d5236d1 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -997,12 +997,25 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain,
else if (TREE_CODE (ftype) == REAL_TYPE
&& TREE_CODE (type) == REAL_TYPE)
{
- if ((same_type_p (ftype, long_double_type_node)
- && (same_type_p (type, double_type_node)
- || same_type_p (type, float_type_node)))
- || (same_type_p (ftype, double_type_node)
- && same_type_p (type, float_type_node))
- || (TYPE_PRECISION (type) < TYPE_PRECISION (ftype)))
+ if ((extended_float_type_p (ftype) || extended_float_type_p (type))
+ ? /* "from a floating-point type T to another floating-point type
+ whose floating-point conversion rank is neither greater than
+ nor equal to that of T".
+ So, it is ok if
+ cp_compare_floating_point_conversion_ranks (ftype, type)
+ returns -2 (type has greater conversion rank than ftype)
+ or [-1..1] (type has equal conversion rank as ftype, possibly
+ different subrank. Only do this if at least one of the
+ types is extended floating-point type, otherwise keep doing
+ what we did before (for the sake of non-standard
+ backend types). */
+ cp_compare_floating_point_conversion_ranks (ftype, type) >= 2
+ : ((same_type_p (ftype, long_double_type_node)
+ && (same_type_p (type, double_type_node)
+ || same_type_p (type, float_type_node)))
+ || (same_type_p (ftype, double_type_node)
+ && same_type_p (type, float_type_node))
+ || (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))))
{
if (TREE_CODE (init) == REAL_CST)
{
@@ -1118,6 +1131,15 @@ array_string_literal_compatible_p (tree type, tree init)
if (ordinary_char_type_p (to_char_type)
&& ordinary_char_type_p (from_char_type))
return true;
+
+ /* P2513 (C++20/C++23): "an array of char or unsigned char may
+ be initialized by a UTF-8 string literal, or by such a string
+ literal enclosed in braces." */
+ if (from_char_type == char8_type_node
+ && (to_char_type == char_type_node
+ || to_char_type == unsigned_char_type_node))
+ return true;
+
return false;
}
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index e91aee3..dcfca64 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -2335,7 +2335,7 @@ layout_struct_initializer (StructDeclaration *sd)
{
StructLiteralExp *sle = StructLiteralExp::create (sd->loc, sd, NULL);
- if (!sd->fill (sd->loc, sle->elements, true))
+ if (!sd->fill (sd->loc, *sle->elements, true))
gcc_unreachable ();
sle->type = sd->type;
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 85fc49d..a4c46f3 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-817610b16d0f0f469b9fbb28c000956fb910c43f
+4219ba670ce9ff92f3e874f0f048f2c28134c008
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index f4b5e8a..edca17f 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -355,23 +355,22 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
* false if any errors occur.
* Otherwise, returns true and the missing arguments will be pushed in elements[].
*/
- final bool fill(const ref Loc loc, Expressions* elements, bool ctorinit)
+ final bool fill(const ref Loc loc, ref Expressions elements, bool ctorinit)
{
//printf("AggregateDeclaration::fill() %s\n", toChars());
assert(sizeok == Sizeok.done);
- assert(elements);
const nfields = nonHiddenFields();
bool errors = false;
size_t dim = elements.dim;
elements.setDim(nfields);
foreach (size_t i; dim .. nfields)
- (*elements)[i] = null;
+ elements[i] = null;
// Fill in missing any elements with default initializers
foreach (i; 0 .. nfields)
{
- if ((*elements)[i])
+ if (elements[i])
continue;
auto vd = fields[i];
@@ -389,7 +388,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
if (!vd.isOverlappedWith(v2))
continue;
- if ((*elements)[j])
+ if (elements[j])
{
vx = null;
break;
@@ -489,10 +488,10 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
else
e = telem.defaultInitLiteral(loc);
}
- (*elements)[fieldi] = e;
+ elements[fieldi] = e;
}
}
- foreach (e; *elements)
+ foreach (e; elements)
{
if (e && e.op == EXP.error)
return false;
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index d91e35e..f0909e3 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -125,7 +125,7 @@ public:
bool determineSize(const Loc &loc);
virtual void finalizeSize() = 0;
uinteger_t size(const Loc &loc) override final;
- bool fill(const Loc &loc, Expressions *elements, bool ctorinit);
+ bool fill(const Loc &loc, Expressions &elements, bool ctorinit);
Type *getType() override final;
bool isDeprecated() const override final; // is aggregate deprecated?
void setDeprecated();
diff --git a/gcc/d/dmd/apply.d b/gcc/d/dmd/apply.d
index ac2c80e..3b73771 100644
--- a/gcc/d/dmd/apply.d
+++ b/gcc/d/dmd/apply.d
@@ -16,6 +16,7 @@ import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.expression;
+import dmd.root.array;
import dmd.visitor;
bool walkPostorder(Expression e, StoppableVisitor v)
@@ -86,12 +87,10 @@ public:
return stop;
}
- bool doCond(Expressions* e)
+ extern(D) bool doCond(Expression[] e)
{
- if (!e)
- return false;
- for (size_t i = 0; i < e.dim && !stop; i++)
- doCond((*e)[i]);
+ for (size_t i = 0; i < e.length && !stop; i++)
+ doCond(e[i]);
return stop;
}
@@ -110,13 +109,13 @@ public:
override void visit(NewExp e)
{
//printf("NewExp::apply(): %s\n", toChars());
- doCond(e.thisexp) || doCond(e.arguments) || applyTo(e);
+ doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e);
}
override void visit(NewAnonClassExp e)
{
//printf("NewAnonClassExp::apply(): %s\n", toChars());
- doCond(e.thisexp) || doCond(e.arguments) || applyTo(e);
+ doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e);
}
override void visit(TypeidExp e)
@@ -143,13 +142,13 @@ public:
override void visit(CallExp e)
{
//printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
- doCond(e.e1) || doCond(e.arguments) || applyTo(e);
+ doCond(e.e1) || doCond(e.arguments.peekSlice()) || applyTo(e);
}
override void visit(ArrayExp e)
{
//printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
- doCond(e.e1) || doCond(e.arguments) || applyTo(e);
+ doCond(e.e1) || doCond(e.arguments.peekSlice()) || applyTo(e);
}
override void visit(SliceExp e)
@@ -159,12 +158,12 @@ public:
override void visit(ArrayLiteralExp e)
{
- doCond(e.basis) || doCond(e.elements) || applyTo(e);
+ doCond(e.basis) || doCond(e.elements.peekSlice()) || applyTo(e);
}
override void visit(AssocArrayLiteralExp e)
{
- doCond(e.keys) || doCond(e.values) || applyTo(e);
+ doCond(e.keys.peekSlice()) || doCond(e.values.peekSlice()) || applyTo(e);
}
override void visit(StructLiteralExp e)
@@ -173,13 +172,13 @@ public:
return;
int old = e.stageflags;
e.stageflags |= stageApply;
- doCond(e.elements) || applyTo(e);
+ doCond(e.elements.peekSlice()) || applyTo(e);
e.stageflags = old;
}
override void visit(TupleExp e)
{
- doCond(e.e0) || doCond(e.exps) || applyTo(e);
+ doCond(e.e0) || doCond(e.exps.peekSlice()) || applyTo(e);
}
override void visit(CondExp e)
diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d
index 272e751..f07a6f4 100644
--- a/gcc/d/dmd/arrayop.d
+++ b/gcc/d/dmd/arrayop.d
@@ -129,8 +129,7 @@ Expression arrayOp(BinExp e, Scope* sc)
return arrayOpInvalidError(e);
auto tiargs = new Objects();
- auto args = new Expressions();
- buildArrayOp(sc, e, tiargs, args);
+ auto args = buildArrayOp(sc, e, tiargs);
import dmd.dtemplate : TemplateDeclaration;
__gshared TemplateDeclaration arrayOp;
@@ -184,7 +183,7 @@ Expression arrayOp(BinAssignExp e, Scope* sc)
* using reverse polish notation (RPN) to encode order of operations.
* Encode operations as string arguments, using a "u" prefix for unary operations.
*/
-private void buildArrayOp(Scope* sc, Expression e, Objects* tiargs, Expressions* args)
+private Expressions* buildArrayOp(Scope* sc, Expression e, Objects* tiargs)
{
extern (C++) final class BuildArrayOpVisitor : Visitor
{
@@ -194,11 +193,11 @@ private void buildArrayOp(Scope* sc, Expression e, Objects* tiargs, Expressions*
Expressions* args;
public:
- extern (D) this(Scope* sc, Objects* tiargs, Expressions* args)
+ extern (D) this(Scope* sc, Objects* tiargs)
{
this.sc = sc;
this.tiargs = tiargs;
- this.args = args;
+ this.args = new Expressions();
}
override void visit(Expression e)
@@ -252,8 +251,9 @@ private void buildArrayOp(Scope* sc, Expression e, Objects* tiargs, Expressions*
}
}
- scope v = new BuildArrayOpVisitor(sc, tiargs, args);
+ scope v = new BuildArrayOpVisitor(sc, tiargs);
e.accept(v);
+ return v.args;
}
/***********************************************
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index b569a9c..3472d1c 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -1431,7 +1431,7 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
if (auto sc = _scope)
{
_scope = null;
- arrayExpressionSemantic(atts, sc);
+ arrayExpressionSemantic(atts.peekSlice(), sc);
}
auto exps = new Expressions();
if (userAttribDecl && userAttribDecl !is this)
@@ -1554,7 +1554,7 @@ int foreachUda(Dsymbol sym, Scope* sc, int delegate(Expression) dg)
return 0;
auto udas = sym.userAttribDecl.getAttributes();
- arrayExpressionSemantic(udas, sc, true);
+ arrayExpressionSemantic(udas.peekSlice(), sc, true);
return udas.each!((uda) {
if (!uda.isTupleExp())
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index 088ca61..09e3833 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -111,13 +111,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
auto ts = tbNext.baseElemOf().isTypeStruct();
if (ts)
{
- import dmd.id : Id;
-
auto sd = ts.sym;
const id = ce.f.ident;
- if (sd.postblit &&
- (id == Id._d_arrayctor || id == Id._d_arraysetctor ||
- id == Id._d_arrayassign_l || id == Id._d_arrayassign_r))
+ if (sd.postblit && isArrayConstructionOrAssign(id))
{
checkFuncThrows(ce, sd.postblit);
return;
diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d
index e118d70..8204961 100644
--- a/gcc/d/dmd/chkformat.d
+++ b/gcc/d/dmd/chkformat.d
@@ -1079,386 +1079,210 @@ Format parseGenericFormatSpecifier(scope const char[] format,
return specifier; // success
}
-unittest
+@("parseGenericFormatSpecifier") unittest
{
- /* parseGenericFormatSpecifier
- */
-
char genSpecifier;
size_t idx;
- assert(parseGenericFormatSpecifier("hhd", idx, genSpecifier) == Format.hhd);
- assert(genSpecifier == 'd');
-
- idx = 0;
- assert(parseGenericFormatSpecifier("hn", idx, genSpecifier) == Format.hn);
- assert(genSpecifier == 'n');
-
- idx = 0;
- assert(parseGenericFormatSpecifier("ji", idx, genSpecifier) == Format.jd);
- assert(genSpecifier == 'i');
+ void testG(string fmtStr, Format expectedFormat, char expectedGenSpecifier)
+ {
+ idx = 0;
+ assert(parseGenericFormatSpecifier(fmtStr, idx, genSpecifier) == expectedFormat);
+ assert(genSpecifier == expectedGenSpecifier);
+ }
- idx = 0;
- assert(parseGenericFormatSpecifier("lu", idx, genSpecifier) == Format.lu);
- assert(genSpecifier == 'u');
+ testG("hhd", Format.hhd, 'd');
+ testG("hn", Format.hn, 'n');
+ testG("ji", Format.jd, 'i');
+ testG("lu", Format.lu, 'u');
idx = 0;
assert(parseGenericFormatSpecifier("k", idx, genSpecifier) == Format.error);
+}
- /* parsePrintfFormatSpecifier
- */
-
- bool widthStar;
- bool precisionStar;
-
- // one for each Format
- idx = 0;
- assert(parsePrintfFormatSpecifier("%d", idx, widthStar, precisionStar) == Format.d);
- assert(idx == 2);
- assert(!widthStar && !precisionStar);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%ld", idx, widthStar, precisionStar) == Format.ld);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%lld", idx, widthStar, precisionStar) == Format.lld);
- assert(idx == 4);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%jd", idx, widthStar, precisionStar) == Format.jd);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%zd", idx, widthStar, precisionStar) == Format.zd);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%td", idx, widthStar, precisionStar) == Format.td);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%g", idx, widthStar, precisionStar) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%Lg", idx, widthStar, precisionStar) == Format.Lg);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%p", idx, widthStar, precisionStar) == Format.p);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%n", idx, widthStar, precisionStar) == Format.n);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%ln", idx, widthStar, precisionStar) == Format.ln);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%lln", idx, widthStar, precisionStar) == Format.lln);
- assert(idx == 4);
+@("parsePrintfFormatSpecifier") unittest
+{
+ bool useGNUExts = false;
- idx = 0;
- assert(parsePrintfFormatSpecifier("%hn", idx, widthStar, precisionStar) == Format.hn);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%hhn", idx, widthStar, precisionStar) == Format.hhn);
- assert(idx == 4);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%jn", idx, widthStar, precisionStar) == Format.jn);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%zn", idx, widthStar, precisionStar) == Format.zn);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%tn", idx, widthStar, precisionStar) == Format.tn);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%c", idx, widthStar, precisionStar) == Format.c);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%lc", idx, widthStar, precisionStar) == Format.lc);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%s", idx, widthStar, precisionStar) == Format.s);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%ls", idx, widthStar, precisionStar) == Format.ls);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%%", idx, widthStar, precisionStar) == Format.percent);
- assert(idx == 2);
-
- // Synonyms
- idx = 0;
- assert(parsePrintfFormatSpecifier("%i", idx, widthStar, precisionStar) == Format.d);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%u", idx, widthStar, precisionStar) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%o", idx, widthStar, precisionStar) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%x", idx, widthStar, precisionStar) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%X", idx, widthStar, precisionStar) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%f", idx, widthStar, precisionStar) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%F", idx, widthStar, precisionStar) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%G", idx, widthStar, precisionStar) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%a", idx, widthStar, precisionStar) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%La", idx, widthStar, precisionStar) == Format.Lg);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%A", idx, widthStar, precisionStar) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%lg", idx, widthStar, precisionStar) == Format.lg);
- assert(idx == 3);
-
- // width, precision
- idx = 0;
- assert(parsePrintfFormatSpecifier("%*d", idx, widthStar, precisionStar) == Format.d);
- assert(idx == 3);
- assert(widthStar && !precisionStar);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%.*d", idx, widthStar, precisionStar) == Format.d);
- assert(idx == 4);
- assert(!widthStar && precisionStar);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%*.*d", idx, widthStar, precisionStar) == Format.d);
- assert(idx == 5);
- assert(widthStar && precisionStar);
-
- // Too short formats
- {
- foreach (s; ["%", "%-", "%+", "% ", "%#", "%0", "%*", "%1", "%19", "%.", "%.*", "%.1", "%.12",
- "%j", "%z", "%t", "%l", "%h", "%ll", "%hh"])
- {
- idx = 0;
- assert(parsePrintfFormatSpecifier(s, idx, widthStar, precisionStar) == Format.error);
- assert(idx == s.length);
- }
- }
-
- // Undefined format combinations
- {
- foreach (s; ["%#d", "%llg", "%jg", "%zg", "%tg", "%hg", "%hhg",
- "%#c", "%0c", "%jc", "%zc", "%tc", "%Lc", "%hc", "%hhc", "%llc",
- "%#s", "%0s", "%js", "%zs", "%ts", "%Ls", "%hs", "%hhs", "%lls",
- "%jp", "%zp", "%tp", "%Lp", "%hp", "%lp", "%hhp", "%llp",
- "%-n", "%+n", "% n", "%#n", "%0n", "%*n", "%1n", "%19n", "%.n", "%.*n", "%.1n", "%.12n", "%Ln", "%K"])
- {
- idx = 0;
- assert(parsePrintfFormatSpecifier(s, idx, widthStar, precisionStar) == Format.error);
- assert(idx == s.length);
- }
- }
-
- /* parseScanfFormatSpecifier
- */
+ size_t idx = 0;
+ bool widthStar;
+ bool precisionStar;
- bool asterisk;
+ void testP(string fmtStr, Format expectedFormat, size_t expectedIdx)
+ {
+ idx = 0;
+ assert(parsePrintfFormatSpecifier(fmtStr, idx, widthStar, precisionStar, useGNUExts) == expectedFormat);
+ assert(idx == expectedIdx);
+ }
// one for each Format
- idx = 0;
- assert(parseScanfFormatSpecifier("%d", idx, asterisk) == Format.d);
- assert(idx == 2);
- assert(!asterisk);
+ testP("%d", Format.d, 2);
+ assert(!widthStar && !precisionStar);
+
+ testP("%ld", Format.ld, 3);
+ testP("%lld", Format.lld, 4);
+ testP("%jd", Format.jd, 3);
+ testP("%zd", Format.zd, 3);
+ testP("%td", Format.td, 3);
+ testP("%g", Format.g, 2);
+ testP("%Lg", Format.Lg, 3);
+ testP("%p", Format.p, 2);
+ testP("%n", Format.n, 2);
+ testP("%ln", Format.ln, 3);
+ testP("%lln", Format.lln, 4);
+ testP("%hn", Format.hn, 3);
+ testP("%hhn", Format.hhn, 4);
+ testP("%jn", Format.jn, 3);
+ testP("%zn", Format.zn, 3);
+ testP("%tn", Format.tn, 3);
+ testP("%c", Format.c, 2);
+ testP("%lc", Format.lc, 3);
+ testP("%s", Format.s, 2);
+ testP("%ls", Format.ls, 3);
+ testP("%%", Format.percent, 2);
- idx = 0;
- assert(parseScanfFormatSpecifier("%hhd", idx, asterisk) == Format.hhd);
- assert(idx == 4);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%hd", idx, asterisk) == Format.hd);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%ld", idx, asterisk) == Format.ld);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%lld", idx, asterisk) == Format.lld);
- assert(idx == 4);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%jd", idx, asterisk) == Format.jd);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%zd", idx, asterisk) == Format.zd);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%td", idx, asterisk,) == Format.td);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%u", idx, asterisk) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%hhu", idx, asterisk,) == Format.hhu);
- assert(idx == 4);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%hu", idx, asterisk) == Format.hu);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%lu", idx, asterisk) == Format.lu);
- assert(idx == 3);
+ // Synonyms
+ testP("%i", Format.d, 2);
+ testP("%u", Format.u, 2);
+ testP("%o", Format.u, 2);
+ testP("%x", Format.u, 2);
+ testP("%X", Format.u, 2);
+ testP("%f", Format.g, 2);
+ testP("%F", Format.g, 2);
+ testP("%G", Format.g, 2);
+ testP("%a", Format.g, 2);
+ testP("%La", Format.Lg, 3);
+ testP("%A", Format.g, 2);
+ testP("%lg", Format.lg, 3);
+
+ // width, precision
+ testP("%*d", Format.d, 3);
+ assert(widthStar && !precisionStar);
+
+ testP("%.*d", Format.d, 4);
+ assert(!widthStar && precisionStar);
+
+ testP("%*.*d", Format.d, 5);
+ assert(widthStar && precisionStar);
- idx = 0;
- assert(parseScanfFormatSpecifier("%llu", idx, asterisk) == Format.llu);
- assert(idx == 4);
+ // Too short formats
+ foreach (s; ["%", "%-", "%+", "% ", "%#", "%0", "%*", "%1", "%19", "%.", "%.*", "%.1", "%.12",
+ "%j", "%z", "%t", "%l", "%h", "%ll", "%hh"])
+ {
+ testP(s, Format.error, s.length);
+ }
- idx = 0;
- assert(parseScanfFormatSpecifier("%ju", idx, asterisk) == Format.ju);
- assert(idx == 3);
+ // Undefined format combinations
+ foreach (s; ["%#d", "%llg", "%jg", "%zg", "%tg", "%hg", "%hhg",
+ "%#c", "%0c", "%jc", "%zc", "%tc", "%Lc", "%hc", "%hhc", "%llc",
+ "%#s", "%0s", "%js", "%zs", "%ts", "%Ls", "%hs", "%hhs", "%lls",
+ "%jp", "%zp", "%tp", "%Lp", "%hp", "%lp", "%hhp", "%llp",
+ "%-n", "%+n", "% n", "%#n", "%0n", "%*n", "%1n", "%19n", "%.n", "%.*n", "%.1n", "%.12n", "%Ln", "%K"])
+ {
+ testP(s, Format.error, s.length);
+ }
- idx = 0;
- assert(parseScanfFormatSpecifier("%g", idx, asterisk) == Format.g);
- assert(idx == 2);
+ testP("%C", Format.lc, 2);
+ testP("%S", Format.ls, 2);
- idx = 0;
- assert(parseScanfFormatSpecifier("%lg", idx, asterisk) == Format.lg);
- assert(idx == 3);
+ // GNU extensions: explicitly toggle ISO/GNU flag.
+ foreach (s; ["%jm", "%zm", "%tm", "%Lm", "%hm", "%hhm", "%lm", "%llm",
+ "%#m", "%+m", "%-m", "% m", "%0m"])
+ {
+ useGNUExts = false;
+ testP(s, Format.error, s.length);
+ useGNUExts = true;
+ testP(s, Format.error, s.length);
+ }
- idx = 0;
- assert(parseScanfFormatSpecifier("%Lg", idx, asterisk) == Format.Lg);
- assert(idx == 3);
+ foreach (s; ["%m", "%md", "%mz", "%mc", "%mm", "%msyz", "%ml", "%mlz", "%mlc", "%mlm"])
+ {
+ // valid cases, all parsed as `%m`
+ // GNU printf()
+ useGNUExts = true;
+ testP(s, Format.GNU_m, 2);
- idx = 0;
- assert(parseScanfFormatSpecifier("%p", idx, asterisk) == Format.p);
- assert(idx == 2);
+ // ISO printf()
+ useGNUExts = false;
+ testP(s, Format.error, 2);
+ }
+}
- idx = 0;
- assert(parseScanfFormatSpecifier("%s", idx, asterisk) == Format.s);
- assert(idx == 2);
+@("parseScanfFormatSpecifier") unittest
+{
+ size_t idx;
+ bool asterisk;
- idx = 0;
- assert(parseScanfFormatSpecifier("%ls", idx, asterisk,) == Format.ls);
- assert(idx == 3);
+ void testS(string fmtStr, Format expectedFormat, size_t expectedIdx)
+ {
+ idx = 0;
+ assert(parseScanfFormatSpecifier(fmtStr, idx, asterisk) == expectedFormat);
+ assert(idx == expectedIdx);
+ }
- idx = 0;
- assert(parseScanfFormatSpecifier("%%", idx, asterisk) == Format.percent);
- assert(idx == 2);
+ // one for each Format
+ testS("%d", Format.d, 2);
+ testS("%hhd", Format.hhd, 4);
+ testS("%hd", Format.hd, 3);
+ testS("%ld", Format.ld, 3);
+ testS("%lld", Format.lld, 4);
+ testS("%jd", Format.jd, 3);
+ testS("%zd", Format.zd, 3);
+ testS("%td", Format.td, 3);
+ testS("%u", Format.u, 2);
+ testS("%hhu", Format.hhu, 4);
+ testS("%hu", Format.hu, 3);
+ testS("%lu", Format.lu, 3);
+ testS("%llu", Format.llu, 4);
+ testS("%ju", Format.ju, 3);
+ testS("%g", Format.g, 2);
+ testS("%lg", Format.lg, 3);
+ testS("%Lg", Format.Lg, 3);
+ testS("%p", Format.p, 2);
+ testS("%s", Format.s, 2);
+ testS("%ls", Format.ls, 3);
+ testS("%%", Format.percent, 2);
// Synonyms
- idx = 0;
- assert(parseScanfFormatSpecifier("%i", idx, asterisk) == Format.d);
- assert(idx == 2);
+ testS("%i", Format.d, 2);
+ testS("%n", Format.n, 2);
- idx = 0;
- assert(parseScanfFormatSpecifier("%n", idx, asterisk) == Format.n);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%o", idx, asterisk) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%x", idx, asterisk) == Format.u);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%f", idx, asterisk) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%e", idx, asterisk) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%a", idx, asterisk) == Format.g);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%c", idx, asterisk) == Format.c);
- assert(idx == 2);
+ testS("%o", Format.u, 2);
+ testS("%x", Format.u, 2);
+ testS("%f", Format.g, 2);
+ testS("%e", Format.g, 2);
+ testS("%a", Format.g, 2);
+ testS("%c", Format.c, 2);
// asterisk
- idx = 0;
- assert(parseScanfFormatSpecifier("%*d", idx, asterisk) == Format.d);
- assert(idx == 3);
+ testS("%*d", Format.d, 3);
assert(asterisk);
- idx = 0;
- assert(parseScanfFormatSpecifier("%9ld", idx, asterisk) == Format.ld);
- assert(idx == 4);
+ testS("%9ld", Format.ld, 4);
assert(!asterisk);
- idx = 0;
- assert(parseScanfFormatSpecifier("%*25984hhd", idx, asterisk) == Format.hhd);
- assert(idx == 10);
+ testS("%*25984hhd", Format.hhd, 10);
assert(asterisk);
// scansets
- idx = 0;
- assert(parseScanfFormatSpecifier("%[a-zA-Z]", idx, asterisk) == Format.s);
- assert(idx == 9);
+ testS("%[a-zA-Z]", Format.s, 9);
assert(!asterisk);
- idx = 0;
- assert(parseScanfFormatSpecifier("%*25l[a-z]", idx, asterisk) == Format.ls);
- assert(idx == 10);
+ testS("%*25l[a-z]", Format.ls, 10);
assert(asterisk);
- idx = 0;
- assert(parseScanfFormatSpecifier("%[]]", idx, asterisk) == Format.s);
- assert(idx == 4);
+ testS("%[]]", Format.s, 4);
assert(!asterisk);
- idx = 0;
- assert(parseScanfFormatSpecifier("%[^]]", idx, asterisk) == Format.s);
- assert(idx == 5);
+ testS("%[^]]", Format.s, 5);
assert(!asterisk);
// Too short formats
foreach (s; ["%", "% ", "%#", "%0", "%*", "%1", "%19",
"%j", "%z", "%t", "%l", "%h", "%ll", "%hh", "%K"])
{
- idx = 0;
- assert(parseScanfFormatSpecifier(s, idx, asterisk) == Format.error);
- assert(idx == s.length);
+
+ testS(s, Format.error, s.length);
}
@@ -1468,18 +1292,16 @@ unittest
"%jp", "%zp", "%tp", "%Lp", "%hp", "%lp", "%hhp", "%llp",
"%-", "%+", "%#", "%0", "%.", "%Ln"])
{
- idx = 0;
- assert(parseScanfFormatSpecifier(s, idx, asterisk) == Format.error);
- assert(idx == s.length);
+
+ testS(s, Format.error, s.length);
}
// Invalid scansets
foreach (s; ["%[]", "%[^", "%[^]", "%[s", "%[0-9lld", "%[", "%l[^]"])
{
- idx = 0;
- assert(parseScanfFormatSpecifier(s, idx, asterisk) == Format.error);
- assert(idx == s.length);
+
+ testS(s, Format.error, s.length);
}
// Posix extensions
@@ -1488,95 +1310,19 @@ unittest
"%LC", "%lC", "%llC", "%jC", "%tC", "%hC", "%hhC", "%zC",
"%LS", "%lS", "%llS", "%jS", "%tS", "%hS", "%hhS", "%zS"])
{
- idx = 0;
- assert(parseScanfFormatSpecifier(s, idx, asterisk) == Format.error);
- assert(idx == s.length);
- }
- idx = 0;
- assert(parseScanfFormatSpecifier("%mc", idx, asterisk) == Format.POSIX_ms);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%ms", idx, asterisk) == Format.POSIX_ms);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%m[0-9]", idx, asterisk) == Format.POSIX_ms);
- assert(idx == 7);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%mlc", idx, asterisk) == Format.POSIX_mls);
- assert(idx == 4);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%mls", idx, asterisk) == Format.POSIX_mls);
- assert(idx == 4);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%ml[^0-9]", idx, asterisk) == Format.POSIX_mls);
- assert(idx == 9);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%mC", idx, asterisk) == Format.POSIX_mls);
- assert(idx == 3);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%mS", idx, asterisk) == Format.POSIX_mls);
- assert(idx == 3);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%C", idx, widthStar, precisionStar) == Format.lc);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%C", idx, asterisk) == Format.lc);
- assert(idx == 2);
-
- idx = 0;
- assert(parsePrintfFormatSpecifier("%S", idx, widthStar, precisionStar) == Format.ls);
- assert(idx == 2);
-
- idx = 0;
- assert(parseScanfFormatSpecifier("%S", idx, asterisk) == Format.ls);
- assert(idx == 2);
-
- // GNU extensions: explicitly toggle ISO/GNU flag.
- // ISO printf()
- bool useGNUExts = false;
- {
- foreach (s; ["%jm", "%zm", "%tm", "%Lm", "%hm", "%hhm", "%lm", "%llm",
- "%#m", "%+m", "%-m", "% m", "%0m"])
- {
- idx = 0;
- assert(parsePrintfFormatSpecifier(s, idx, widthStar, precisionStar, useGNUExts) == Format.error);
- assert(idx == s.length);
- }
- foreach (s; ["%m", "%md", "%mz", "%mc", "%mm", "%msyz", "%ml", "%mlz", "%mlc", "%mlm"])
- {
- idx = 0;
- assert(parsePrintfFormatSpecifier(s, idx, widthStar, precisionStar, useGNUExts) == Format.error);
- assert(idx == 2);
- }
+ testS(s, Format.error, s.length);
}
- // GNU printf()
- useGNUExts = true;
- {
- foreach (s; ["%jm", "%zm", "%tm", "%Lm", "%hm", "%hhm", "%lm", "%llm",
- "%#m", "%+m", "%-m", "% m", "%0m"])
- {
- idx = 0;
- assert(parsePrintfFormatSpecifier(s, idx, widthStar, precisionStar, useGNUExts) == Format.error);
- assert(idx == s.length);
- }
-
- // valid cases, all parsed as `%m`
- foreach (s; ["%m", "%md", "%mz", "%mc", "%mm", "%msyz", "%ml", "%mlz", "%mlc", "%mlm"])
- {
- idx = 0;
- assert(parsePrintfFormatSpecifier(s, idx, widthStar, precisionStar, useGNUExts) == Format.GNU_m);
- assert(idx == 2);
- }
- }
+ testS("%mc", Format.POSIX_ms, 3);
+ testS("%ms", Format.POSIX_ms, 3);
+ testS("%m[0-9]", Format.POSIX_ms, 7);
+ testS("%mlc", Format.POSIX_mls, 4);
+ testS("%mls", Format.POSIX_mls, 4);
+ testS("%ml[^0-9]", Format.POSIX_mls, 9);
+ testS("%mC", Format.POSIX_mls, 3);
+ testS("%mS", Format.POSIX_mls, 3);
+
+ testS("%C", Format.lc, 2);
+ testS("%S", Format.ls, 2);
}
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 1a26eaa..ba7d590 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -105,8 +105,7 @@ FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc)
scope er = new NullExp(ad.loc, ad.type); // dummy rvalue
scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
el.type = ad.type;
- Expressions a;
- a.setDim(1);
+ auto a = Expressions(1);
const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.
sc = sc.push();
sc.tinst = null;
@@ -465,8 +464,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
*/
scope er = new NullExp(ad.loc, null); // dummy rvalue
scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
- Expressions a;
- a.setDim(1);
+ auto a = Expressions(1);
bool hasIt(Type tthis)
{
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 2679a63..2c5a4f0 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -1886,15 +1886,6 @@ final class CParser(AST) : Parser!AST
}
if (s !is null)
{
- s = applySpecifier(s, specifier);
- if (level == LVL.local)
- {
- // Wrap the declaration in `extern (C) { declaration }`
- // Necessary for function pointers, but harmless to apply to all.
- auto decls = new AST.Dsymbols(1);
- (*decls)[0] = s;
- s = new AST.LinkDeclaration(s.loc, linkage, decls);
- }
// Saw `asm("name")` in the function, type, or variable definition.
// This is equivalent to `pragma(mangle, "name")` in D
if (asmName)
@@ -1917,6 +1908,15 @@ final class CParser(AST) : Parser!AST
p.mangleOverride = str;
}
}
+ s = applySpecifier(s, specifier);
+ if (level == LVL.local)
+ {
+ // Wrap the declaration in `extern (C) { declaration }`
+ // Necessary for function pointers, but harmless to apply to all.
+ auto decls = new AST.Dsymbols(1);
+ (*decls)[0] = s;
+ s = new AST.LinkDeclaration(s.loc, linkage, decls);
+ }
symbols.push(s);
}
first = false;
@@ -2603,7 +2603,6 @@ final class CParser(AST) : Parser!AST
{
//printf("cparseDeclarator(%d, %p)\n", declarator, t);
AST.Types constTypes; // all the Types that will need `const` applied to them
- constTypes.setDim(0);
AST.Type parseDecl(AST.Type t)
{
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index afd19f3..8ab3873 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -2979,10 +2979,10 @@ Lagain:
return Lret(t);
if (t1n.ty == Tvoid) // pointers to void are always compatible
- return Lret(t2);
+ return Lret(t1);
if (t2n.ty == Tvoid)
- return Lret(t);
+ return Lret(t2);
if (t1.implicitConvTo(t2))
return convert(e1, t2);
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index bc8db44..5bce6b0 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -210,7 +210,7 @@ public:
Dsymbol *aliassym;
const char *kind() const override;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
bool overloadInsert(Dsymbol *s) override;
Dsymbol *toAlias() override;
@@ -625,7 +625,7 @@ public:
FuncDeclaration *syntaxCopy(Dsymbol *) override;
bool functionSemantic();
bool functionSemantic3();
- bool equals(const RootObject *o) const override final;
+ bool equals(const RootObject * const o) const override final;
int overrides(FuncDeclaration *fd);
int findVtblIndex(Dsymbols *vtbl, int dim);
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index 5cc3772..705acd1 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -265,11 +265,16 @@ extern (C++) final class Import : Dsymbol
scopesym.addAccessiblePackage(p, visibility);
foreach (id; packages[1 .. $]) // [b, c]
{
- p = cast(Package) p.symtab.lookup(id);
+ auto sym = p.symtab.lookup(id);
// https://issues.dlang.org/show_bug.cgi?id=17991
// An import of truly empty file/package can happen
// https://issues.dlang.org/show_bug.cgi?id=20151
// Package in the path conflicts with a module name
+ if (sym is null)
+ break;
+ // https://issues.dlang.org/show_bug.cgi?id=23327
+ // Package conflicts with symbol of the same name
+ p = sym.isPackage();
if (p is null)
break;
scopesym.addAccessiblePackage(p, visibility);
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index a9fd0f5..a95d9de 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -2830,7 +2830,7 @@ public:
(*exps)[i] = ex;
}
}
- sd.fill(e.loc, exps, false);
+ sd.fill(e.loc, *exps, false);
auto se = ctfeEmplaceExp!StructLiteralExp(e.loc, sd, exps, e.newtype);
se.origin = se;
@@ -4778,12 +4778,6 @@ public:
// If `_d_HookTraceImpl` is found, resolve the underlying hook and replace `e` and `fd` with it.
removeHookTraceImpl(e, fd);
- bool isArrayConstructionOrAssign(FuncDeclaration fd)
- {
- return fd.ident == Id._d_arrayctor || fd.ident == Id._d_arraysetctor ||
- fd.ident == Id._d_arrayassign_l || fd.ident == Id._d_arrayassign_r;
- }
-
if (fd.ident == Id.__ArrayPostblit || fd.ident == Id.__ArrayDtor)
{
assert(e.arguments.dim == 1);
@@ -4837,11 +4831,11 @@ public:
result = interpretRegion(ae, istate);
return;
}
- else if (isArrayConstructionOrAssign(fd))
+ else if (isArrayConstructionOrAssign(fd.ident))
{
// In expressionsem.d, the following lowerings were performed:
// * `T[x] ea = eb;` to `_d_array{,set}ctor(ea[], eb[]);`.
- // * `ea = eb` (ea and eb are arrays) to `_d_arrayassign_{l,r}(ea[], eb[])`.
+ // * `ea = eb` to `_d_array{,setassign,assign_l,assign_r}(ea[], eb)`.
// The following code will rewrite them back to `ea = eb` and
// then interpret that expression.
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index 25794e2..be0cbcc 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -833,6 +833,23 @@ public:
printf(" parent = %s %s", s.parent.kind(), s.parent.toChars());
printf("\n");
}
+ if (s.parent && s.ident)
+ {
+ if (auto m = s.parent.isModule())
+ {
+ if (m.filetype == FileType.c)
+ {
+ /* C types at global level get mangled into the __C global namespace
+ * to get the same mangling regardless of which module it
+ * is declared in. This works because types are the same if the mangling
+ * is the same.
+ */
+ mangleIdentifier(Id.ImportC, s); // parent
+ mangleIdentifier(s.ident, s);
+ return;
+ }
+ }
+ }
mangleParent(s);
if (s.ident)
mangleIdentifier(s.ident, s);
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index ba83649..e1d5897 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -3294,7 +3294,7 @@ private struct MarkdownLink
* Params:
* buf = an OutBuffer containing the DDoc
* i = the index within `buf` that points to the first character of the URL.
- * If this function succeeds `i` will point just after the the end of the URL.
+ * If this function succeeds `i` will point just after the end of the URL.
* Returns: whether a URL was found and parsed
*/
private bool parseHref(ref OutBuffer buf, ref size_t i)
@@ -3362,7 +3362,7 @@ private struct MarkdownLink
* Params:
* buf = an OutBuffer containing the DDoc
* i = the index within `buf` that points to the first character of the title.
- * If this function succeeds `i` will point just after the the end of the title.
+ * If this function succeeds `i` will point just after the end of the title.
* Returns: whether a title was found and parsed
*/
private bool parseTitle(ref OutBuffer buf, ref size_t i)
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index c940ff0..7e2d02f 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -1544,6 +1544,12 @@ public:
if (flags & IgnoreAmbiguous) // if return NULL on ambiguity
return null;
+
+ /* If two imports from C import files, pick first one, as C has global name space
+ */
+ if (s.isCsymbol() && s2.isCsymbol())
+ continue;
+
if (!(flags & IgnoreErrors))
ScopeDsymbol.multiplyDefined(loc, s, s2);
break;
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index bea4b77..acf0004 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -189,7 +189,7 @@ public:
virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments
Loc getLoc();
const char *locToChars();
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
bool isAnonymous() const;
void error(const Loc &loc, const char *format, ...);
void error(const char *format, ...);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index c3424dc..701f06a 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -58,6 +58,7 @@ import dmd.nspace;
import dmd.objc;
import dmd.opover;
import dmd.parse;
+import dmd.root.array;
import dmd.root.filename;
import dmd.common.outbuffer;
import dmd.root.rmem;
@@ -983,7 +984,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// possibilities.
if (fd && !(dsym.storage_class & (STC.manifest | STC.static_ | STC.gshared | STC.extern_)) && !dsym._init.isVoidInitializer())
{
- //printf("fd = '%s', var = '%s'\n", fd.toChars(), toChars());
+ //printf("fd = '%s', var = '%s'\n", fd.toChars(), dsym.toChars());
if (!ei)
{
ArrayInitializer ai = dsym._init.isArrayInitializer();
@@ -1014,24 +1015,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);
}
- Expression exp = ei.exp;
- Expression e1 = new VarExp(dsym.loc, dsym);
- if (isBlit)
- exp = new BlitExp(dsym.loc, e1, exp);
- else
- exp = new ConstructExp(dsym.loc, e1, exp);
- dsym.canassign++;
- exp = exp.expressionSemantic(sc);
- dsym.canassign--;
- exp = exp.optimize(WANTvalue);
- if (exp.op == EXP.error)
- {
- dsym._init = new ErrorInitializer();
- ei = null;
- }
- else
- ei.exp = exp;
-
if (ei && dsym.isScope())
{
Expression ex = ei.exp.lastComma();
@@ -1054,6 +1037,24 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
f.tookAddressOf--;
}
}
+
+ Expression exp = ei.exp;
+ Expression e1 = new VarExp(dsym.loc, dsym);
+ if (isBlit)
+ exp = new BlitExp(dsym.loc, e1, exp);
+ else
+ exp = new ConstructExp(dsym.loc, e1, exp);
+ dsym.canassign++;
+ exp = exp.expressionSemantic(sc);
+ dsym.canassign--;
+ exp = exp.optimize(WANTvalue);
+ if (exp.op == EXP.error)
+ {
+ dsym._init = new ErrorInitializer();
+ ei = null;
+ }
+ else
+ ei.exp = exp;
}
else
{
@@ -1956,7 +1957,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
//printf("UserAttributeDeclaration::semantic() %p\n", this);
if (uad.decl && !uad._scope)
uad.Dsymbol.setScope(sc); // for function local symbols
- arrayExpressionSemantic(uad.atts, sc, true);
+ arrayExpressionSemantic(uad.atts.peekSlice(), sc, true);
return attribSemantic(uad);
}
@@ -4182,6 +4183,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
dd.errors = true;
return;
}
+
+ if (ad.isClassDeclaration() && ad.classKind == ClassKind.d)
+ {
+ // Class destructors are implicitly `scope`
+ dd.storage_class |= STC.scope_;
+ }
+
if (dd.ident == Id.dtor && dd.semanticRun < PASS.semantic)
ad.userDtors.push(dd);
if (!dd.type)
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 34cae1d..13efc1c 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -1327,7 +1327,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
Loc instLoc = ti.loc;
Objects* tiargs = ti.tiargs;
- auto dedargs = new Objects();
+ auto dedargs = new Objects(parameters.dim);
Objects* dedtypes = &ti.tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
version (none)
@@ -1346,7 +1346,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
assert(_scope);
- dedargs.setDim(parameters.dim);
dedargs.zero();
dedtypes.setDim(parameters.dim);
@@ -1511,7 +1510,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
}
- if (toParent().isModule() || (_scope.stc & STC.static_))
+ if (toParent().isModule())
tthis = null;
if (tthis)
{
@@ -1534,7 +1533,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
// Match attributes of tthis against attributes of fd
- if (fd.type && !fd.isCtorDeclaration())
+ if (fd.type && !fd.isCtorDeclaration() && !(_scope.stc & STC.static_))
{
StorageClass stc = _scope.stc | fd.storage_class2;
// Propagate parent storage class, https://issues.dlang.org/show_bug.cgi?id=5504
@@ -2716,14 +2715,27 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
if (mfa == MATCH.nomatch)
return 0;
- if (mfa > m.last) goto LfIsBetter;
- if (mfa < m.last) goto LlastIsBetter;
+ int firstIsBetter()
+ {
+ td_best = null;
+ ti_best = null;
+ ta_last = MATCH.exact;
+ m.last = mfa;
+ m.lastf = fd;
+ tthis_best = tthis_fd;
+ ov_index = 0;
+ m.count = 1;
+ return 0;
+ }
+
+ if (mfa > m.last) return firstIsBetter();
+ if (mfa < m.last) return 0;
/* See if one of the matches overrides the other.
*/
assert(m.lastf);
- if (m.lastf.overrides(fd)) goto LlastIsBetter;
- if (fd.overrides(m.lastf)) goto LfIsBetter;
+ if (m.lastf.overrides(fd)) return 0;
+ if (fd.overrides(m.lastf)) return firstIsBetter();
/* Try to disambiguate using template-style partial ordering rules.
* In essence, if f() and g() are ambiguous, if f() can call g(),
@@ -2734,8 +2746,8 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
MATCH c1 = fd.leastAsSpecialized(m.lastf);
MATCH c2 = m.lastf.leastAsSpecialized(fd);
//printf("c1 = %d, c2 = %d\n", c1, c2);
- if (c1 > c2) goto LfIsBetter;
- if (c1 < c2) goto LlastIsBetter;
+ if (c1 > c2) return firstIsBetter();
+ if (c1 < c2) return 0;
}
/* The 'overrides' check above does covariant checking only
@@ -2756,12 +2768,12 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
{
if (firstCovariant != Covariant.yes && firstCovariant != Covariant.no)
{
- goto LlastIsBetter;
+ return 0;
}
}
else if (firstCovariant == Covariant.yes || firstCovariant == Covariant.no)
{
- goto LfIsBetter;
+ return firstIsBetter();
}
}
@@ -2780,37 +2792,22 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc,
fd._linkage == m.lastf._linkage)
{
if (fd.fbody && !m.lastf.fbody)
- goto LfIsBetter;
+ return firstIsBetter();
if (!fd.fbody)
- goto LlastIsBetter;
+ return 0;
}
// https://issues.dlang.org/show_bug.cgi?id=14450
// Prefer exact qualified constructor for the creating object type
if (isCtorCall && tf.mod != m.lastf.type.mod)
{
- if (tthis.mod == tf.mod) goto LfIsBetter;
- if (tthis.mod == m.lastf.type.mod) goto LlastIsBetter;
+ if (tthis.mod == tf.mod) return firstIsBetter();
+ if (tthis.mod == m.lastf.type.mod) return 0;
}
m.nextf = fd;
m.count++;
return 0;
-
- LlastIsBetter:
- return 0;
-
- LfIsBetter:
- td_best = null;
- ti_best = null;
- ta_last = MATCH.exact;
- m.last = mfa;
- m.lastf = fd;
- tthis_best = tthis_fd;
- ov_index = 0;
- m.count = 1;
- return 0;
-
}
int applyTemplate(TemplateDeclaration td)
@@ -3844,10 +3841,20 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
tp = (*parameters)[i];
else
{
+ Loc loc;
+ // The "type" (it hasn't been resolved yet) of the function parameter
+ // does not have a location but the parameter it is related to does,
+ // so we use that for the resolution (better error message).
+ if (inferStart < parameters.dim)
+ {
+ TemplateParameter loctp = (*parameters)[inferStart];
+ loc = loctp.loc;
+ }
+
Expression e;
Type tx;
Dsymbol s;
- taa.index.resolve(Loc.initial, sc, e, tx, s);
+ taa.index.resolve(loc, sc, e, tx, s);
edim = s ? getValue(s) : getValue(e);
}
}
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 4f06bac..7ba0a96 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -1423,10 +1423,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
* auto dg = () return { return &x; }
* Because dg.ptr points to x, this is returning dt.ptr+offset
*/
- if (global.params.useDIP1000 == FeatureState.enabled)
- {
- sc.func.storage_class |= STC.return_ | STC.returninferred;
- }
+ sc.func.storage_class |= STC.return_ | STC.returninferred;
}
}
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index f871fade..42b4dd4 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -7197,6 +7197,26 @@ extern(D) Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag
}
}
+/**
+ * Verify if the given identifier is any of
+ * _d_array{ctor,setctor,setassign,assign_l, assign_r}.
+ *
+ * Params:
+ * id = the identifier to verify
+ *
+ * Returns:
+ * `true` if the identifier corresponds to a construction of assignement
+ * runtime hook, `false` otherwise.
+ */
+bool isArrayConstructionOrAssign(const Identifier id)
+{
+ import dmd.id : Id;
+
+ return id == Id._d_arrayctor || id == Id._d_arraysetctor ||
+ id == Id._d_arrayassign_l || id == Id._d_arrayassign_r ||
+ id == Id._d_arraysetassign;
+}
+
/******************************
* Provide efficient way to implement isUnaExp(), isBinExp(), isBinAssignExp()
*/
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 9ab1cab..c9e3978 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -250,7 +250,7 @@ public:
static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
dinteger_t toInteger() override;
real_t toReal() override;
real_t toImaginary() override;
@@ -280,7 +280,7 @@ public:
static RealExp *create(const Loc &loc, real_t value, Type *type);
static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
dinteger_t toInteger() override;
uinteger_t toUInteger() override;
real_t toReal() override;
@@ -297,7 +297,7 @@ public:
static ComplexExp *create(const Loc &loc, complex_t value, Type *type);
static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type);
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
dinteger_t toInteger() override;
uinteger_t toUInteger() override;
real_t toReal() override;
@@ -358,7 +358,7 @@ public:
class NullExp final : public Expression
{
public:
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
Optional<bool> toBool() override;
StringExp *toStringExp() override;
void accept(Visitor *v) override { v->visit(this); }
@@ -377,7 +377,7 @@ public:
static StringExp *create(const Loc &loc, const char *s);
static StringExp *create(const Loc &loc, const void *s, d_size_t len);
static void emplace(UnionExp *pue, const Loc &loc, const char *s);
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
char32_t getCodeUnit(d_size_t i) const;
void setCodeUnit(d_size_t i, char32_t c);
StringExp *toStringExp() override;
@@ -408,7 +408,7 @@ public:
static TupleExp *create(const Loc &loc, Expressions *exps);
TupleExp *syntaxCopy() override;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -423,7 +423,7 @@ public:
static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
ArrayLiteralExp *syntaxCopy() override;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
Expression *getElement(d_size_t i); // use opIndex instead
Expression *opIndex(d_size_t i);
Optional<bool> toBool() override;
@@ -439,7 +439,7 @@ public:
Expressions *values;
OwnedBy ownedByCtfe;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
AssocArrayLiteralExp *syntaxCopy() override;
Optional<bool> toBool() override;
@@ -477,7 +477,7 @@ public:
OwnedBy ownedByCtfe;
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
StructLiteralExp *syntaxCopy() override;
Expression *getField(Type *type, unsigned offset);
int getFieldIndex(Type *type, unsigned offset);
@@ -583,7 +583,7 @@ class VarExp final : public SymbolExp
public:
bool delegateWasExtracted;
static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
bool isLvalue() override;
Expression *toLvalue(Scope *sc, Expression *e) override;
Expression *modifiableLvalue(Scope *sc, Expression *e) override;
@@ -612,7 +612,7 @@ public:
TemplateDeclaration *td;
TOK tok;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
FuncExp *syntaxCopy() override;
const char *toChars() const override;
bool checkType() override;
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 3114100..8a4a13c 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -62,6 +62,7 @@ import dmd.opover;
import dmd.optimize;
import dmd.parse;
import dmd.printast;
+import dmd.root.array;
import dmd.root.ctfloat;
import dmd.root.file;
import dmd.root.filename;
@@ -336,22 +337,18 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* p
/******************************
* Perform semantic() on an array of Expressions.
*/
-bool arrayExpressionSemantic(Expressions* exps, Scope* sc, bool preserveErrors = false)
+extern(D) bool arrayExpressionSemantic(
+ Expression[] exps, Scope* sc, bool preserveErrors = false)
{
bool err = false;
- if (exps)
+ foreach (ref e; exps)
{
- foreach (ref e; *exps)
- {
- if (e)
- {
- auto e2 = e.expressionSemantic(sc);
- if (e2.op == EXP.error)
- err = true;
- if (preserveErrors || e2.op != EXP.error)
- e = e2;
- }
- }
+ if (e is null) continue;
+ auto e2 = e.expressionSemantic(sc);
+ if (e2.op == EXP.error)
+ err = true;
+ if (preserveErrors || e2.op != EXP.error)
+ e = e2;
}
return err;
}
@@ -443,7 +440,7 @@ private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident)
}
if (!s)
- return ue.e1.type.getProperty(sc, loc, ident, 0);
+ return ue.e1.type.getProperty(sc, loc, ident, 0, ue.e1);
FuncDeclaration f = s.isFuncDeclaration();
if (f)
@@ -550,7 +547,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
if (!global.endGagging(errors))
return e;
- if (arrayExpressionSemantic(originalArguments, sc))
+ if (arrayExpressionSemantic(originalArguments.peekSlice(), sc))
return ErrorExp.get();
/* fall down to UFCS */
@@ -3111,7 +3108,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (e.basis)
e.basis = e.basis.expressionSemantic(sc);
- if (arrayExpressionSemantic(e.elements, sc) || (e.basis && e.basis.op == EXP.error))
+ if (arrayExpressionSemantic(e.elements.peekSlice(), sc) || (e.basis && e.basis.op == EXP.error))
return setError();
expandTuples(e.elements);
@@ -3154,8 +3151,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
// Run semantic() on each element
- bool err_keys = arrayExpressionSemantic(e.keys, sc);
- bool err_vals = arrayExpressionSemantic(e.values, sc);
+ bool err_keys = arrayExpressionSemantic(e.keys.peekSlice(), sc);
+ bool err_vals = arrayExpressionSemantic(e.values.peekSlice(), sc);
if (err_keys || err_vals)
return setError();
@@ -3201,7 +3198,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
// run semantic() on each element
- if (arrayExpressionSemantic(e.elements, sc))
+ if (arrayExpressionSemantic(e.elements.peekSlice(), sc))
return setError();
expandTuples(e.elements);
@@ -3213,7 +3210,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* Fill out remainder of elements[] with default initializers for fields[]
*/
- if (!e.sd.fill(e.loc, e.elements, false))
+ if (!e.sd.fill(e.loc, *e.elements, false))
{
/* An error in the initializer needs to be recorded as an error
* in the enclosing function or template, since the initializer
@@ -3524,7 +3521,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.newtype = exp.type; // in case type gets cast to something else
Type tb = exp.type.toBasetype();
//printf("tb: %s, deco = %s\n", tb.toChars(), tb.deco);
- if (arrayExpressionSemantic(exp.arguments, sc))
+ if (arrayExpressionSemantic(exp.arguments.peekSlice(), sc))
{
return setError();
}
@@ -3672,7 +3669,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
- if (cd.disableNew)
+ if (cd.disableNew && !exp.onstack)
{
exp.error("cannot allocate `class %s` with `new` because it is annotated with `@disable new()`",
originalNewtype.toChars());
@@ -3807,7 +3804,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!sd.fit(exp.loc, sc, exp.arguments, tb))
return setError();
- if (!sd.fill(exp.loc, exp.arguments, false))
+ if (!sd.fill(exp.loc, *exp.arguments, false))
return setError();
if (checkFrameAccess(exp.loc, sc, sd, exp.arguments ? exp.arguments.dim : 0))
@@ -4259,7 +4256,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (FuncExp fe = exp.e1.isFuncExp())
{
- if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments))
+ if (arrayExpressionSemantic(exp.arguments.peekSlice(), sc) ||
+ preFunctionParameters(sc, exp.arguments))
return setError();
// Run e1 semantic even if arguments have any errors
@@ -4497,7 +4495,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = exp.e1;
return;
}
- if (arrayExpressionSemantic(exp.arguments, sc) || preFunctionParameters(sc, exp.arguments))
+ if (arrayExpressionSemantic(exp.arguments.peekSlice(), sc) ||
+ preFunctionParameters(sc, exp.arguments))
return setError();
// Check for call operator overload
@@ -4543,7 +4542,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
goto Lx;
auto sle = new StructLiteralExp(exp.loc, sd, null, exp.e1.type);
- if (!sd.fill(exp.loc, sle.elements, true))
+ if (!sd.fill(exp.loc, *sle.elements, true))
return setError();
if (checkFrameAccess(exp.loc, sc, sd, sle.elements.dim))
return setError();
@@ -4614,7 +4613,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
Expression e;
- // Make sure to use the the enum type itself rather than its
+ // Make sure to use the enum type itself rather than its
// base type
// https://issues.dlang.org/show_bug.cgi?id=16346
if (exp.e1.type.ty == Tenum)
@@ -8661,7 +8660,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (sd.isNested())
{
auto sle = new StructLiteralExp(loc, sd, null, t);
- if (!sd.fill(loc, sle.elements, true))
+ if (!sd.fill(loc, *sle.elements, true))
return ErrorExp.get();
if (checkFrameAccess(loc, sc, sd, sle.elements.dim))
return ErrorExp.get();
@@ -9991,15 +9990,15 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
/***************************************
- * Lower AssignExp to `_d_arrayassign_{l,r}` if needed.
+ * Lower AssignExp to `_d_array{setassign,assign_l,assign_r}` if needed.
*
* Params:
* ae = the AssignExp to be lowered
* fromCommaExp = indicates whether `ae` is part of a CommaExp or not,
* so no unnecessary temporay variable is created.
* Returns:
- * a CommaExp contiaining call a to `_d_arrayassign_{l,r}` if needed or
- * `ae` otherwise
+ * a CommaExp contiaining call a to `_d_array{setassign,assign_l,assign_r}`
+ * if needed or `ae` otherwise
*/
private Expression lowerArrayAssign(AssignExp ae, bool fromCommaExp = false)
{
@@ -10007,12 +10006,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (t1b.ty != Tsarray && t1b.ty != Tarray)
return ae;
- const isArrayAssign =
- (ae.e1.isSliceExp || ae.e1.type.ty == Tsarray) &&
+ const isArrayAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
(ae.e2.type.ty == Tsarray || ae.e2.type.ty == Tarray) &&
- (ae.e1.type.nextOf && ae.e2.type.nextOf && ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf));
+ (ae.e1.type.nextOf() && ae.e2.type.nextOf() && ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf()));
- if (!isArrayAssign)
+ const isArraySetAssign = (ae.e1.isSliceExp() || ae.e1.type.ty == Tsarray) &&
+ (ae.e1.type.nextOf() && ae.e2.type.implicitConvTo(ae.e1.type.nextOf()));
+
+ if (!isArrayAssign && !isArraySetAssign)
return ae;
const ts = t1b.nextOf().baseElemOf().isTypeStruct();
@@ -10020,9 +10021,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return ae;
Expression res;
- auto func = ae.e2.isLvalue || ae.e2.isSliceExp ? Id._d_arrayassign_l : Id._d_arrayassign_r;
+ Identifier func = isArraySetAssign ? Id._d_arraysetassign :
+ ae.e2.isLvalue() || ae.e2.isSliceExp() ? Id._d_arrayassign_l : Id._d_arrayassign_r;
- // Lower to `.object._d_arrayassign_l{r}(e1, e2)``
+ // Lower to `.object._d_array{setassign,assign_l,assign_r}(e1, e2)``
Expression id = new IdentifierExp(ae.loc, Id.empty);
id = new DotIdExp(ae.loc, id, Id.object);
id = new DotIdExp(ae.loc, id, func);
@@ -10032,10 +10034,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
.expressionSemantic(sc));
Expression eValue2, value2 = ae.e2;
- if (ae.e2.isLvalue)
- value2 = new CastExp(ae.loc, ae.e2, ae.e2.type.nextOf.arrayOf)
+ if (isArrayAssign && value2.isLvalue())
+ value2 = new CastExp(ae.loc, ae.e2, ae.e2.type.nextOf.arrayOf())
.expressionSemantic(sc);
- else if (!fromCommaExp)
+ else if (!fromCommaExp &&
+ (isArrayAssign || (isArraySetAssign && !value2.isLvalue())))
{
// Rvalues from CommaExps were introduced in `visit(AssignExp)`
// and are temporary variables themselves. Rvalues from trivial
@@ -10044,7 +10047,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// `__assigntmp` will be destroyed together with the array `ae.e1`.
// When `ae.e2` is a variadic arg array, it is also `scope`, so
// `__assigntmp` may also be scope.
- auto vd = copyToTemp(STC.rvalue | STC.nodtor | STC.scope_, "__assigntmp", ae.e2);
+ StorageClass stc = STC.nodtor;
+ if (isArrayAssign)
+ stc |= STC.rvalue | STC.scope_;
+
+ auto vd = copyToTemp(stc, "__assigntmp", ae.e2);
eValue2 = new DeclarationExp(vd.loc, vd).expressionSemantic(sc);
value2 = new VarExp(vd.loc, vd).expressionSemantic(sc);
}
@@ -10052,7 +10059,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Expression ce = new CallExp(ae.loc, id, arguments);
res = Expression.combine(eValue2, ce).expressionSemantic(sc);
- res = Expression.combine(res, ae.e1).expressionSemantic(sc);
+ if (isArrayAssign)
+ res = Expression.combine(res, ae.e1).expressionSemantic(sc);
if (global.params.verbose)
message("lowered %s =>\n %s", ae.toChars(), res.toChars());
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 4c09474..bcae282 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -3216,11 +3216,12 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
}
}
- if (tiargs && arrayObjectIsError(tiargs) ||
- fargs && arrayObjectIsError(cast(Objects*)fargs))
- {
+ if (tiargs && arrayObjectIsError(tiargs))
return null;
- }
+ if (fargs !is null)
+ foreach (arg; *fargs)
+ if (isError(arg))
+ return null;
MatchAccumulator m;
functionResolve(m, s, loc, sc, tiargs, tthis, fargs, null);
@@ -3758,9 +3759,9 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration
// backend
bool deferToObj;
- extern (D) this(const ref Loc loc, const ref Loc endloc, Type type, TOK tok, ForeachStatement fes, Identifier id = null)
+ extern (D) this(const ref Loc loc, const ref Loc endloc, Type type, TOK tok, ForeachStatement fes, Identifier id = null, StorageClass storage_class = STC.undefined_)
{
- super(loc, endloc, null, STC.undefined_, type);
+ super(loc, endloc, null, storage_class, type);
this.ident = id ? id : Id.empty;
this.tok = tok;
this.fes = fes;
@@ -3774,7 +3775,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration
{
//printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars());
assert(!s);
- auto f = new FuncLiteralDeclaration(loc, endloc, type.syntaxCopy(), tok, fes, ident);
+ auto f = new FuncLiteralDeclaration(loc, endloc, type.syntaxCopy(), tok, fes, ident, storage_class & STC.auto_);
f.treq = treq; // don't need to copy
FuncDeclaration.syntaxCopy(f);
return f;
@@ -3833,9 +3834,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration
{
Expression exp = s.exp;
if (exp && !exp.type.equals(tret))
- {
- s.exp = exp.castTo(sc, tret);
- }
+ s.exp = exp.implicitCastTo(sc, tret);
}
}
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 7d4fbc3..7a840ff 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -84,13 +84,10 @@ int parseExtAsmOperands(Parser)(Parser p, GccAsmStatement s)
case TOK.string_:
constraint = p.parsePrimaryExp();
- // @@@DEPRECATED_2.101@@@
- // Old parser allowed omitting parentheses around the expression.
- // Deprecated in 2.091. Can be made permanent error after 2.100
if (p.token.value != TOK.leftParenthesis)
{
arg = p.parseAssignExp();
- deprecation(arg.loc, "`%s` must be surrounded by parentheses", arg.toChars());
+ error(arg.loc, "`%s` must be surrounded by parentheses", arg.toChars());
}
else
{
@@ -527,6 +524,9 @@ unittest
// Found ',' when expecting ':'
q{ asm { "", "";
} },
+
+ // https://issues.dlang.org/show_bug.cgi?id=20593
+ q{ asm { "instruction" : : "operand" 123; } },
];
foreach (test; passAsmTests)
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 6695faa..48ca766 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -319,6 +319,7 @@ immutable Msgtable[] msgtable =
{ "_aaApply2" },
{ "_d_arrayctor" },
{ "_d_arraysetctor" },
+ { "_d_arraysetassign" },
{ "_d_arrayassign_l" },
{ "_d_arrayassign_r" },
@@ -511,6 +512,7 @@ immutable Msgtable[] msgtable =
{ "wchar_t" },
// for C compiler
+ { "ImportC", "__C" },
{ "__tag" },
{ "dllimport" },
{ "dllexport" },
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index 164a5f3..523b5b8 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -167,6 +167,7 @@ extern (C++) final class ArrayInitializer : Initializer
uint dim; // length of array being initialized
Type type; // type that array will be used to initialize
bool sem; // true if semantic() is run
+ bool isCarray; // C array semantics
extern (D) this(const ref Loc loc)
{
diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h
index 296c31d..977157f 100644
--- a/gcc/d/dmd/init.h
+++ b/gcc/d/dmd/init.h
@@ -78,6 +78,7 @@ public:
unsigned dim; // length of array being initialized
Type *type; // type that array will be used to initialize
bool sem; // true if semantic() is run
+ bool isCarray; // C array semantics
bool isAssociativeArray() const;
Expression *toAssocArrayLiteral();
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index a576712..ef39f59 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -225,7 +225,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
assert(sc);
auto tm = vd.type.addMod(t.mod);
auto iz = i.value[j].initializerSemantic(sc, tm, needInterpret);
- auto ex = iz.initializerToExpression();
+ auto ex = iz.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0);
if (ex.op == EXP.error)
{
errors = true;
@@ -243,7 +243,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
// Make a StructLiteralExp out of elements[]
auto sle = new StructLiteralExp(i.loc, sd, elements, t);
- if (!sd.fill(i.loc, elements, false))
+ if (!sd.fill(i.loc, *elements, false))
return err();
sle.type = t;
auto ie = new ExpInitializer(i.loc, sle);
@@ -272,7 +272,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
uint length;
const(uint) amax = 0x80000000;
bool errors = false;
- //printf("ArrayInitializer::semantic(%s)\n", t.toChars());
+ //printf("ArrayInitializer::semantic(%s), ai: %s %p\n", t.toChars(), i.toChars(), i);
if (i.sem) // if semantic() already run
{
return i;
@@ -374,11 +374,22 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
}
if (auto tsa = t.isTypeSArray())
{
- uinteger_t edim = tsa.dim.toInteger();
- if (i.dim > edim && !(tsa.isIncomplete() && (sc.flags & SCOPE.Cfile)))
+ if (sc.flags & SCOPE.Cfile && tsa.isIncomplete())
{
- error(i.loc, "array initializer has %u elements, but array length is %llu", i.dim, edim);
- return err();
+ // Change to array of known length
+ auto tn = tsa.next.toBasetype();
+ tsa = new TypeSArray(tn, new IntegerExp(Loc.initial, i.dim, Type.tsize_t));
+ tx = tsa; // rewrite caller's type
+ i.type = tsa; // remember for later passes
+ }
+ else
+ {
+ uinteger_t edim = tsa.dim.toInteger();
+ if (i.dim > edim)
+ {
+ error(i.loc, "array initializer has %u elements, but array length is %llu", i.dim, edim);
+ return err();
+ }
}
}
if (errors)
@@ -394,6 +405,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
error(i.loc, "array dimension %llu exceeds max of %llu", ulong(i.dim), ulong(amax / sz));
return err();
}
+ //printf("returns ai: %s\n", i.toChars());
return i;
}
@@ -661,295 +673,380 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
Initializer visitC(CInitializer ci)
{
- if (ci.sem) // if semantic() already run
- return ci;
//printf("CInitializer::semantic() (%s) %s\n", t.toChars(), ci.toChars());
- ci.sem = true;
+ /* Rewrite CInitializer into ExpInitializer, ArrayInitializer, or StructInitializer
+ */
t = t.toBasetype();
- ci.type = t; // later passes will need this
-
- auto dil = ci.initializerList[];
- size_t i = 0; // index into dil[]
- const uint amax = 0x8000_0000;
- bool errors;
/* If `{ expression }` return the expression initializer
*/
ExpInitializer isBraceExpression()
{
+ auto dil = ci.initializerList[];
return (dil.length == 1 && !dil[0].designatorList)
? dil[0].initializer.isExpInitializer()
: null;
}
- /* Convert struct initializer into ExpInitializer
+ /********************************
*/
- Initializer structs(TypeStruct ts)
+ bool overlaps(VarDeclaration field, VarDeclaration[] fields, StructInitializer si)
{
- //printf("structs %s\n", ts.toChars());
+ foreach (fld; fields)
+ {
+ if (field.isOverlappedWith(fld))
+ {
+ // look for initializer corresponding with fld
+ foreach (i, ident; si.field[])
+ {
+ if (ident == fld.ident && si.value[i])
+ return true; // already an initializer for `field`
+ }
+ }
+ }
+ return false;
+ }
+
+ /* Run semantic on ExpInitializer, see if it represents entire struct ts
+ */
+ bool representsStruct(ExpInitializer ei, TypeStruct ts)
+ {
+ if (needInterpret)
+ sc = sc.startCTFE();
+ ei.exp = ei.exp.expressionSemantic(sc);
+ ei.exp = resolveProperties(sc, ei.exp);
+ if (needInterpret)
+ sc = sc.endCTFE();
+ return ei.exp.implicitConvTo(ts) != MATCH.nomatch; // initializer represents the entire struct
+ }
+
+ /* If { } are omitted from substructs, use recursion to reconstruct where
+ * brackets go
+ * Params:
+ * ts = substruct to initialize
+ * index = index into ci.initializer, updated
+ * Returns: struct initializer for this substruct
+ */
+ Initializer subStruct()(TypeStruct ts, ref size_t index)
+ {
+ //printf("subStruct(ts: %s, index %d)\n", ts.toChars(), cast(int)index);
+
+ auto si = new StructInitializer(ci.loc);
StructDeclaration sd = ts.sym;
sd.size(ci.loc);
if (sd.sizeok != Sizeok.done)
{
- errors = true;
+ index = ci.initializerList.length;
return err();
}
- const nfields = sd.nonHiddenFields();
- auto elements = new Expressions(nfields);
- auto elems = (*elements)[];
- foreach (ref elem; elems)
- elem = null;
+ const nfields = sd.fields.length;
- FieldLoop:
- for (size_t fieldi = 0; fieldi < nfields; ++fieldi)
+ foreach (fieldi; 0 .. nfields)
{
- if (i == dil.length)
- break;
-
- auto di = dil[i];
- if (di.designatorList)
+ if (index >= ci.initializerList.length)
+ break; // ran out of initializers
+ auto di = ci.initializerList[index];
+ if (di.designatorList && fieldi != 0)
+ break; // back to top level
+ else
{
- error(ci.loc, "C designator-list not supported yet");
- errors = true;
- break;
+ VarDeclaration field;
+ while (1) // skip field if it overlaps with previously seen fields
+ {
+ field = sd.fields[fieldi];
+ ++fieldi;
+ if (!overlaps(field, sd.fields[], si))
+ break;
+ if (fieldi == nfields)
+ break;
+ }
+ auto tn = field.type.toBasetype();
+ auto tnsa = tn.isTypeSArray();
+ auto tns = tn.isTypeStruct();
+ auto ix = di.initializer;
+ if (tnsa && ix.isExpInitializer())
+ {
+ ExpInitializer ei = ix.isExpInitializer();
+ if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
+ {
+ si.addInit(field.ident, ei);
+ ++index;
+ }
+ else
+ si.addInit(field.ident, subArray(tnsa, index)); // fwd ref of subArray is why subStruct is a template
+ }
+ else if (tns && ix.isExpInitializer())
+ {
+ /* Disambiguate between an exp representing the entire
+ * struct, and an exp representing the first field of the struct
+ */
+ if (representsStruct(ix.isExpInitializer(), tns)) // initializer represents the entire struct
+ {
+ si.addInit(field.ident, initializerSemantic(ix, sc, tn, needInterpret));
+ ++index;
+ }
+ else // field initializers for struct
+ si.addInit(field.ident, subStruct(tns, index)); // the first field
+ }
+ else
+ {
+ si.addInit(field.ident, ix);
+ ++index;
+ }
}
+ }
+ //printf("subStruct() returns ai: %s, index: %d\n", si.toChars(), cast(int)index);
+ return si;
+ }
- VarDeclaration vd = sd.fields[fieldi];
+ /* If { } are omitted from subarrays, use recursion to reconstruct where
+ * brackets go
+ * Params:
+ * tsa = subarray to initialize
+ * index = index into ci.initializer, updated
+ * Returns: array initializer for this subarray
+ */
+ Initializer subArray(TypeSArray tsa, ref size_t index)
+ {
+ //printf("array(tsa: %s, index %d)\n", tsa.toChars(), cast(int)index);
+ if (tsa.isIncomplete())
+ {
+ // C11 6.2.5-20 "element type shall be complete whenever the array type is specified"
+ assert(0); // should have been detected by parser
+ }
- // Check for overlapping initializations (can happen with unions)
- foreach (k, v2; sd.fields[0 .. nfields])
+ auto tnsa = tsa.nextOf().toBasetype().isTypeSArray();
+
+ auto ai = new ArrayInitializer(ci.loc);
+ ai.isCarray = true;
+
+ foreach (n; 0 .. cast(size_t)tsa.dim.toInteger())
+ {
+ if (index >= ci.initializerList.length)
+ break; // ran out of initializers
+ auto di = ci.initializerList[index];
+ if (di.designatorList)
+ break; // back to top level
+ else if (tnsa && di.initializer.isExpInitializer())
{
- if (vd.isOverlappedWith(v2) && elems[k])
+ ExpInitializer ei = di.initializer.isExpInitializer();
+ if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
{
- continue FieldLoop; // skip it
+ ai.addInit(null, ei);
+ ++index;
}
+ else
+ ai.addInit(null, subArray(tnsa, index));
}
-
- ++i;
-
- // Convert initializer to Expression `ex`
- assert(sc);
- auto tm = vd.type.addMod(ts.mod);
- auto iz = di.initializer.initializerSemantic(sc, tm, needInterpret);
- auto ex = iz.initializerToExpression(null, true);
- if (ex.op == EXP.error)
+ else
{
- errors = true;
- continue;
+ ai.addInit(null, di.initializer);
+ ++index;
}
-
- elems[fieldi] = ex;
}
- if (errors)
- return err();
-
- // Make a StructLiteralExp out of elements[]
- Type tx = ts;
- auto sle = new StructLiteralExp(ci.loc, sd, elements, tx);
- if (!sd.fill(ci.loc, elements, false))
- return err();
- sle.type = tx;
- auto ie = new ExpInitializer(ci.loc, sle);
- return ie.initializerSemantic(sc, tx, needInterpret);
+ //printf("array() returns ai: %s, index: %d\n", ai.toChars(), cast(int)index);
+ return ai;
}
if (auto ts = t.isTypeStruct())
{
- auto ei = structs(ts);
- if (errors)
- return err();
- if (i < dil.length)
+ auto si = new StructInitializer(ci.loc);
+ StructDeclaration sd = ts.sym;
+ sd.size(ci.loc); // run semantic() on sd to get fields
+ if (sd.sizeok != Sizeok.done)
{
- error(ci.loc, "%d extra initializer(s) for `struct %s`", cast(int)(dil.length - i), ts.toChars());
return err();
}
- return ei;
- }
+ const nfields = sd.fields.length;
- auto tsa = t.isTypeSArray();
- if (!tsa)
- {
- /* Not an array. See if it is `{ exp }` which can be
- * converted to an ExpInitializer
- */
- if (ExpInitializer ei = isBraceExpression())
- {
- return ei.initializerSemantic(sc, t, needInterpret);
- }
-
- error(ci.loc, "C non-array initializer (%s) %s not supported yet", t.toChars(), ci.toChars());
- return err();
- }
+ size_t fieldi = 0;
- /* If it's an array of integral being initialized by `{ string }`
- * replace with `string`
- */
- auto tn = t.nextOf();
- if (tn.isintegral())
- {
- if (ExpInitializer ei = isBraceExpression())
+ for (size_t index = 0; index < ci.initializerList.length; )
{
- if (ei.exp.isStringExp())
- return ei.initializerSemantic(sc, t, needInterpret);
+ auto di = ci.initializerList[index];
+ auto dlist = di.designatorList;
+ if (dlist)
+ {
+ const length = (*dlist).length;
+ if (length == 0 || !(*dlist)[0].ident)
+ {
+ error(ci.loc, "`.identifier` expected for C struct field initializer `%s`", ci.toChars());
+ return err();
+ }
+ if (length > 1)
+ {
+ error(ci.loc, "only 1 designator currently allowed for C struct field initializer `%s`", ci.toChars());
+ return err();
+ }
+ auto id = (*dlist)[0].ident;
+ foreach (k, f; sd.fields[]) // linear search for now
+ {
+ if (f.ident == id)
+ {
+ fieldi = k;
+ si.addInit(id, di.initializer);
+ ++fieldi;
+ ++index;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (fieldi == nfields)
+ break;
+ VarDeclaration field;
+ while (1) // skip field if it overlaps with previously seen fields
+ {
+ field = sd.fields[fieldi];
+ ++fieldi;
+ if (!overlaps(field, sd.fields[], si))
+ break;
+ if (fieldi == nfields)
+ break;
+ }
+ auto tn = field.type.toBasetype();
+ auto tnsa = tn.isTypeSArray();
+ auto tns = tn.isTypeStruct();
+ auto ix = di.initializer;
+ if (tnsa && ix.isExpInitializer())
+ {
+ ExpInitializer ei = ix.isExpInitializer();
+ if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
+ {
+ si.addInit(field.ident, ei);
+ ++index;
+ }
+ else
+ si.addInit(field.ident, subArray(tnsa, index));
+ }
+ else if (tns && ix.isExpInitializer())
+ {
+ /* Disambiguate between an exp representing the entire
+ * struct, and an exp representing the first field of the struct
+ */
+ if (representsStruct(ix.isExpInitializer(), tns)) // initializer represents the entire struct
+ {
+ si.addInit(field.ident, initializerSemantic(ix, sc, tn, needInterpret));
+ ++index;
+ }
+ else // field initializers for struct
+ si.addInit(field.ident, subStruct(tns, index)); // the first field
+ }
+ else
+ {
+ si.addInit(field.ident, di.initializer);
+ ++index;
+ }
+ }
}
+ return initializerSemantic(si, sc, t, needInterpret);
}
-
- /* Support recursion to handle un-braced array initializers
- * Params:
- * t = element type
- * dim = max number of elements
- * simple = true if array of simple elements
- * Returns:
- * # of elements in array
- */
- size_t array(Type t, size_t dim, ref bool simple)
+ else if (auto ta = t.isTypeSArray())
{
- //printf(" type %s i %d dim %d dil.length = %d\n", t.toChars(), cast(int)i, cast(int)dim, cast(int)dil.length);
- auto tn = t.nextOf().toBasetype();
- auto tnsa = tn.isTypeSArray();
- if (tnsa && tnsa.isIncomplete())
- {
- // C11 6.2.5-20 "element type shall be complete whenever the array type is specified"
- error(ci.loc, "incomplete element type `%s` not allowed", tnsa.toChars());
- errors = true;
- return 1;
- }
- if (i == dil.length)
- return 0;
- size_t n;
- const nelems = tnsa ? cast(size_t)tnsa.dim.toInteger() : 0;
+ auto tn = t.nextOf().toBasetype(); // element type of array
- /* Run initializerSemantic on a single element.
+ /* If it's an array of integral being initialized by `{ string }`
+ * replace with `string`
*/
- Initializer elem(Initializer ie)
+ if (tn.isintegral())
{
- ++i;
- auto tnx = tn; // in case initializerSemantic tries to change it
- ie = ie.initializerSemantic(sc, tnx, needInterpret);
- if (ie.isErrorInitializer())
- errors = true;
- assert(tnx == tn); // sub-types should not be modified
- return ie;
+ if (ExpInitializer ei = isBraceExpression())
+ {
+ if (ei.exp.isStringExp())
+ return ei.initializerSemantic(sc, t, needInterpret);
+ }
}
- foreach (j; 0 .. dim)
+ auto tnsa = tn.isTypeSArray(); // array of array
+ auto tns = tn.isTypeStruct(); // array of struct
+
+ auto ai = new ArrayInitializer(ci.loc);
+ ai.isCarray = true;
+ for (size_t index = 0; index < ci.initializerList.length; )
{
- auto di = dil[i];
- if (di.designatorList)
- {
- error(ci.loc, "C designator-list not supported yet");
- errors = true;
- break;
- }
- if (tnsa && di.initializer.isExpInitializer())
+ auto di = ci.initializerList[index];
+ if (auto dlist = di.designatorList)
{
- // no braces enclosing array initializer, so recurse
- array(tnsa, nelems, simple);
- }
- else if (auto tns = tn.isTypeStruct())
- {
- if (auto ei = di.initializer.isExpInitializer())
+ const length = (*dlist).length;
+ if (length == 0 || !(*dlist)[0].exp)
+ {
+ error(ci.loc, "`[ constant-expression ]` expected for C array element initializer `%s`", ci.toChars());
+ return err();
+ }
+ if (length > 1)
+ {
+ error(ci.loc, "only 1 designator currently allowed for C array element initializer `%s`", ci.toChars());
+ return err();
+ }
+ //printf("tn: %s, di.initializer: %s\n", tn.toChars(), di.initializer.toChars());
+ auto ix = di.initializer;
+ if (tnsa && ix.isExpInitializer())
+ {
+ // Wrap initializer in [ ]
+ auto ain = new ArrayInitializer(ci.loc);
+ ain.addInit(null, di.initializer);
+ ix = ain;
+ ai.addInit((*dlist)[0].exp, initializerSemantic(ix, sc, tn, needInterpret));
+ ++index;
+ }
+ else if (tns && ix.isExpInitializer())
{
- // no braces enclosing struct initializer
-
/* Disambiguate between an exp representing the entire
* struct, and an exp representing the first field of the struct
- */
- if (needInterpret)
- sc = sc.startCTFE();
- ei.exp = ei.exp.expressionSemantic(sc);
- ei.exp = resolveProperties(sc, ei.exp);
- if (needInterpret)
- sc = sc.endCTFE();
- if (ei.exp.implicitConvTo(tn))
- di.initializer = elem(di.initializer); // the whole struct
- else
+ */
+ if (representsStruct(ix.isExpInitializer(), tns)) // initializer represents the entire struct
{
- simple = false;
- dil[n].initializer = structs(tns); // the first field
+ ai.addInit((*dlist)[0].exp, initializerSemantic(ix, sc, tn, needInterpret));
+ ++index;
}
+ else // field initializers for struct
+ ai.addInit((*dlist)[0].exp, subStruct(tns, index)); // the first field
+ }
+ else
+ {
+ ai.addInit((*dlist)[0].exp, initializerSemantic(ix, sc, tn, needInterpret));
+ ++index;
+ }
+ }
+ else if (tnsa && di.initializer.isExpInitializer())
+ {
+ ExpInitializer ei = di.initializer.isExpInitializer();
+ if (ei.exp.isStringExp() && tnsa.nextOf().isintegral())
+ {
+ ai.addInit(null, ei);
+ ++index;
}
else
- dil[n].initializer = elem(di.initializer);
+ ai.addInit(null, subArray(tnsa, index));
+ }
+ else if (tns && di.initializer.isExpInitializer())
+ {
+ /* Disambiguate between an exp representing the entire
+ * struct, and an exp representing the first field of the struct
+ */
+ if (representsStruct(di.initializer.isExpInitializer(), tns)) // initializer represents the entire struct
+ {
+ ai.addInit(null, initializerSemantic(di.initializer, sc, tn, needInterpret));
+ ++index;
+ }
+ else // field initializers for struct
+ ai.addInit(null, subStruct(tns, index)); // the first field
}
else
{
- di.initializer = elem(di.initializer);
+ ai.addInit(null, initializerSemantic(di.initializer, sc, tn, needInterpret));
+ ++index;
}
- ++n;
- if (i == dil.length)
- break;
- }
- //printf(" n: %d i: %d\n", cast(int)n, cast(int)i);
- return n;
- }
-
- size_t dim = tsa.isIncomplete() ? dil.length : cast(size_t)tsa.dim.toInteger();
- bool simple = true;
- auto newdim = array(t, dim, simple);
-
- if (errors)
- return err();
-
- if (tsa.isIncomplete()) // array of unknown length
- {
- // Change to array of known length
- tsa = new TypeSArray(tn, new IntegerExp(Loc.initial, newdim, Type.tsize_t));
- tx = tsa; // rewrite caller's type
- ci.type = tsa; // remember for later passes
- }
- const uinteger_t edim = tsa.dim.toInteger();
- if (i < dil.length)
- {
- error(ci.loc, "%d extra initializer(s) for static array length of %d", cast(int)(dil.length - i), cast(int)edim);
- return err();
- }
-
- const sz = tn.size(); // element size
- if (sz == SIZE_INVALID)
- return err();
- bool overflow;
- const max = mulu(edim, sz, overflow);
- if (overflow || max >= amax)
- {
- error(ci.loc, "array dimension %llu exceeds max of %llu", ulong(edim), ulong(amax / sz));
- return err();
- }
-
- /* If an array of simple elements, replace with an ArrayInitializer
- */
- auto tnb = tn.toBasetype();
- if (!tnb.isTypeSArray() && (!tnb.isTypeStruct() || simple))
- {
- auto ai = new ArrayInitializer(ci.loc);
- ai.dim = cast(uint) dil.length;
- ai.index.setDim(dil.length);
- ai.value.setDim(dil.length);
- foreach (const j; 0 .. dil.length)
- {
- ai.index[j] = null;
- ai.value[j] = dil[j].initializer;
}
- auto ty = tx;
- return ai.initializerSemantic(sc, ty, needInterpret);
+ return initializerSemantic(ai, sc, tx, needInterpret);
}
-
- if (newdim < ci.initializerList.length && tnb.isTypeStruct())
+ else if (ExpInitializer ei = isBraceExpression())
+ return visitExp(ei);
+ else
{
- // https://issues.dlang.org/show_bug.cgi?id=22375
- // initializerList can be bigger than the number of actual elements
- // to initialize for array of structs because it is not required
- // for values to have proper bracing.
- // i.e: These are all valid initializers for `struct{int a,b;}[3]`:
- // {1,2,3,4}, {{1,2},3,4}, {1,2,{3,4}}, {{1,2},{3,4}}
- // In all examples above, the new length of the initializer list
- // has been shortened from four elements to two. This is important,
- // because `dil` is written back to directly, making the lowered
- // initializer `{{1,2},{3,4}}` and not `{{1,2},{3,4},3,4}`.
- ci.initializerList.length = newdim;
+ assert(0);
}
-
- return ci;
}
final switch (init.kind)
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 21bbde8..1de89d4 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -2582,8 +2582,13 @@ class Lexer
{
/* C11 6.4.4.2 doesn't actually care if it is not representable if it is not hex
*/
- const char* suffix = (result == TOK.float32Literal || result == TOK.imaginary32Literal) ? "f" : "";
- error(scanloc, "number `%s%s` is not representable", sbufptr, suffix);
+ const char* suffix = result == TOK.float32Literal ? "f" : result == TOK.float80Literal ? "L" : "";
+ const char* type = [TOK.float32Literal: "`float`".ptr,
+ TOK.float64Literal: "`double`".ptr,
+ TOK.float80Literal: "`real` for the current target".ptr][result];
+ error(scanloc, "number `%s%s` is not representable as a %s", sbufptr, suffix, type);
+ const char* extra = result == TOK.float64Literal ? "`real` literals can be written using the `L` suffix. " : "";
+ errorSupplemental(scanloc, "%shttps://dlang.org/spec/lex.html#floatliteral", extra);
}
debug
{
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 6bfb729..341ce36 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -37,7 +37,7 @@ public:
const char *kind() const override;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
Package *isPackage() override final { return this; }
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index f2da41b..1240f5a 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -936,7 +936,7 @@ extern (C++) abstract class Type : ASTNode
else
{
// If `typeSemantic` succeeded, there may have been deprecations that
- // were gagged due the the `startGagging` above. Run again to display
+ // were gagged due the `startGagging` above. Run again to display
// those deprecations. https://issues.dlang.org/show_bug.cgi?id=19107
if (global.gaggedWarnings > 0)
typeSemantic(tcopy, loc, sc);
@@ -4656,7 +4656,7 @@ extern (C++) final class TypeFunction : TypeNext
// suppress early exit if an error message is wanted,
// so we can check any matching args are valid
if (!pMessage)
- goto Nomatch;
+ return MATCH.nomatch;
}
// too many args; no match
match = MATCH.convert; // match ... with a "conversion" match level
@@ -4669,7 +4669,7 @@ extern (C++) final class TypeFunction : TypeNext
buf.printf("too few arguments, expected `%d`, got `%d`", cast(int)nparams, cast(int)nargs);
if (pMessage)
*pMessage = buf.extractChars();
- goto Nomatch;
+ return MATCH.nomatch;
}
foreach (u, p; parameterList)
@@ -4710,226 +4710,16 @@ extern (C++) final class TypeFunction : TypeNext
MATCH m;
assert(p);
- if (u >= nargs)
- {
- if (p.defaultArg)
- continue;
- // try typesafe variadics
- goto L1;
- }
+
+ // One or more arguments remain
+ if (u < nargs)
{
Expression arg = args[u];
assert(arg);
- //printf("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars());
-
- Type targ = arg.type;
- Type tprm = wildmatch ? p.type.substWildTo(wildmatch) : p.type;
-
- if (p.isLazy() && tprm.ty == Tvoid && targ.ty != Tvoid)
- m = MATCH.convert;
- else
- {
- //printf("%s of type %s implicitConvTo %s\n", arg.toChars(), targ.toChars(), tprm.toChars());
- if (flag)
- {
- // for partial ordering, value is an irrelevant mockup, just look at the type
- m = targ.implicitConvTo(tprm);
- }
- else
- {
- const isRef = p.isReference();
-
- StructDeclaration argStruct, prmStruct;
-
- // first look for a copy constructor
- if (arg.isLvalue() && !isRef && targ.ty == Tstruct && tprm.ty == Tstruct)
- {
- // if the argument and the parameter are of the same unqualified struct type
- argStruct = (cast(TypeStruct)targ).sym;
- prmStruct = (cast(TypeStruct)tprm).sym;
- }
-
- // check if the copy constructor may be called to copy the argument
- if (argStruct && argStruct == prmStruct && argStruct.hasCopyCtor)
- {
- /* this is done by seeing if a call to the copy constructor can be made:
- *
- * typeof(tprm) __copytmp;
- * copytmp.__copyCtor(arg);
- */
- auto tmp = new VarDeclaration(arg.loc, tprm, Identifier.generateId("__copytmp"), null);
- tmp.storage_class = STC.rvalue | STC.temp | STC.ctfe;
- tmp.dsymbolSemantic(sc);
- Expression ve = new VarExp(arg.loc, tmp);
- Expression e = new DotIdExp(arg.loc, ve, Id.ctor);
- e = new CallExp(arg.loc, e, arg);
- //printf("e = %s\n", e.toChars());
- if(.trySemantic(e, sc))
- m = MATCH.exact;
- else
- {
- if (pMessage)
- {
- /* https://issues.dlang.org/show_bug.cgi?id=22202
- *
- * If a function was deduced by semantic on the CallExp,
- * it means that resolveFuncCall completed succesfully.
- * Therefore, there exists a callable copy constructor,
- * however, it cannot be called because scope constraints
- * such as purity, safety or nogc.
- */
- OutBuffer buf;
- auto callExp = e.isCallExp();
- if (auto f = callExp.f)
- {
- char[] s;
- if (!f.isPure && sc.func.setImpure())
- s ~= "pure ";
- if (!f.isSafe() && !f.isTrusted() && sc.setUnsafe())
- s ~= "@safe ";
- if (!f.isNogc && sc.func.setGC())
- s ~= "nogc ";
- if (s)
- {
- s[$-1] = '\0';
- buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr);
- }
- else if (f.isGenerated() && f.isDisabled())
- {
- /* https://issues.dlang.org/show_bug.cgi?id=23097
- * Compiler generated copy constructor failed.
- */
- buf.printf("generating a copy constructor for `struct %s` failed, therefore instances of it are uncopyable",
- argStruct.toChars());
- }
- else
- {
- /* Although a copy constructor may exist, no suitable match was found.
- * i.e: `inout` constructor creates `const` object, not mutable.
- * Fallback to using the original generic error before bugzilla 22202.
- */
- goto Lnocpctor;
- }
- }
- else
- {
- Lnocpctor:
- buf.printf("`struct %s` does not define a copy constructor for `%s` to `%s` copies",
- argStruct.toChars(), targ.toChars(), tprm.toChars());
- }
-
- *pMessage = buf.extractChars();
- }
- m = MATCH.nomatch;
- goto Nomatch;
- }
- }
- else
- {
- import dmd.dcast : cimplicitConvTo;
- m = (sc && sc.flags & SCOPE.Cfile) ? arg.cimplicitConvTo(tprm) : arg.implicitConvTo(tprm);
- }
- }
- //printf("match %d\n", m);
- }
-
- // Non-lvalues do not match ref or out parameters
- if (p.isReference())
- {
- // https://issues.dlang.org/show_bug.cgi?id=13783
- // Don't use toBasetype() to handle enum types.
- Type ta = targ;
- Type tp = tprm;
- //printf("fparam[%d] ta = %s, tp = %s\n", u, ta.toChars(), tp.toChars());
-
- if (m && !arg.isLvalue())
- {
- if (p.storageClass & STC.out_)
- {
- if (pMessage) *pMessage = getParamError(arg, p);
- goto Nomatch;
- }
-
- if (arg.op == EXP.string_ && tp.ty == Tsarray)
- {
- if (ta.ty != Tsarray)
- {
- Type tn = tp.nextOf().castMod(ta.nextOf().mod);
- dinteger_t dim = (cast(StringExp)arg).len;
- ta = tn.sarrayOf(dim);
- }
- }
- else if (arg.op == EXP.slice && tp.ty == Tsarray)
- {
- // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
- if (ta.ty != Tsarray)
- {
- Type tn = ta.nextOf();
- dinteger_t dim = (cast(TypeSArray)tp).dim.toUInteger();
- ta = tn.sarrayOf(dim);
- }
- }
- else if ((p.storageClass & STC.in_) && global.params.previewIn)
- {
- // Allow converting a literal to an `in` which is `ref`
- if (arg.op == EXP.arrayLiteral && tp.ty == Tsarray)
- {
- Type tn = tp.nextOf();
- dinteger_t dim = (cast(TypeSArray)tp).dim.toUInteger();
- ta = tn.sarrayOf(dim);
- }
-
- // Need to make this a rvalue through a temporary
- m = MATCH.convert;
- }
- else if (global.params.rvalueRefParam != FeatureState.enabled ||
- p.storageClass & STC.out_ ||
- !arg.type.isCopyable()) // can't copy to temp for ref parameter
- {
- if (pMessage) *pMessage = getParamError(arg, p);
- goto Nomatch;
- }
- else
- {
- /* in functionParameters() we'll convert this
- * rvalue into a temporary
- */
- m = MATCH.convert;
- }
- }
-
- /* If the match is not already perfect or if the arg
- is not a lvalue then try the `alias this` chain
- see https://issues.dlang.org/show_bug.cgi?id=15674
- and https://issues.dlang.org/show_bug.cgi?id=21905
- */
- if (ta != tp || !arg.isLvalue())
- {
- Type firsttab = ta.toBasetype();
- while (1)
- {
- Type tab = ta.toBasetype();
- Type tat = tab.aliasthisOf();
- if (!tat || !tat.implicitConvTo(tprm))
- break;
- if (tat == tab || tat == firsttab)
- break;
- ta = tat;
- }
- }
-
- /* A ref variable should work like a head-const reference.
- * e.g. disallows:
- * ref T <- an lvalue of const(T) argument
- * ref T[dim] <- an lvalue of const(T[dim]) argument
- */
- if (!ta.constConv(tp))
- {
- if (pMessage) *pMessage = getParamError(arg, p);
- goto Nomatch;
- }
- }
+ m = argumentMatchParameter(this, p, arg, wildmatch, flag, sc, pMessage);
}
+ else if (p.defaultArg)
+ continue;
/* prefer matching the element type rather than the array
* type when more arguments are present with T[]...
@@ -4943,100 +4733,33 @@ extern (C++) final class TypeFunction : TypeNext
L1:
if (parameterList.varargs == VarArg.typesafe && u + 1 == nparams) // if last varargs param
{
- Type tb = p.type.toBasetype();
- TypeSArray tsa;
- dinteger_t sz;
-
- switch (tb.ty)
- {
- case Tsarray:
- tsa = cast(TypeSArray)tb;
- sz = tsa.dim.toInteger();
- if (sz != nargs - u)
- {
- if (pMessage)
- // Windows (Vista) OutBuffer.vprintf issue? 2nd argument always zero
- //*pMessage = getMatchError("expected %d variadic argument(s), not %d", sz, nargs - u);
- if (!global.gag || global.params.showGaggedErrors)
- {
- OutBuffer buf;
- buf.printf("expected %llu variadic argument(s)", sz);
- buf.printf(", not %zu", nargs - u);
- *pMessage = buf.extractChars();
- }
- goto Nomatch;
- }
- goto case Tarray;
- case Tarray:
- {
- TypeArray ta = cast(TypeArray)tb;
- foreach (arg; args[u .. nargs])
- {
- assert(arg);
-
- /* If lazy array of delegates,
- * convert arg(s) to delegate(s)
- */
- Type tret = p.isLazyArray();
- if (tret)
- {
- if (ta.next.equals(arg.type))
- m = MATCH.exact;
- else if (tret.toBasetype().ty == Tvoid)
- m = MATCH.convert;
- else
- {
- m = arg.implicitConvTo(tret);
- if (m == MATCH.nomatch)
- m = arg.implicitConvTo(ta.next);
- }
- }
- else
- m = arg.implicitConvTo(ta.next);
-
- if (m == MATCH.nomatch)
- {
- if (pMessage) *pMessage = getParamError(arg, p);
- goto Nomatch;
- }
- if (m < match)
- match = m;
- }
- goto Ldone;
- }
- case Tclass:
- // Should see if there's a constructor match?
- // Or just leave it ambiguous?
- goto Ldone;
-
- default:
- break;
- }
+ auto trailingArgs = args[u .. $];
+ if (auto vmatch = matchTypeSafeVarArgs(this, p, trailingArgs, pMessage))
+ return vmatch < match ? vmatch : match;
+ // Error message was already generated in `matchTypeSafeVarArgs`
+ return MATCH.nomatch;
}
- if (pMessage && u < nargs)
- *pMessage = getParamError(args[u], p);
- else if (pMessage)
+ if (pMessage && u >= nargs)
*pMessage = getMatchError("missing argument for parameter #%d: `%s`",
u + 1, parameterToChars(p, this, false));
- goto Nomatch;
+ // If an error happened previously, `pMessage` was already filled
+ else if (pMessage && !*pMessage)
+ *pMessage = getParamError(args[u], p);
+
+ return MATCH.nomatch;
}
if (m < match)
match = m; // pick worst match
}
- Ldone:
if (pMessage && !parameterList.varargs && nargs > nparams)
{
// all parameters had a match, but there are surplus args
*pMessage = getMatchError("expected %d argument(s), not %d", nparams, nargs);
- goto Nomatch;
+ return MATCH.nomatch;
}
//printf("match = %d\n", match);
return match;
-
- Nomatch:
- //printf("no match\n");
- return MATCH.nomatch;
}
/+
@@ -6194,6 +5917,11 @@ extern (C++) final class TypeClass : Type
if (t && t.ty == Tclass)
{
ClassDeclaration cd = (cast(TypeClass)t).sym;
+ if (cd.semanticRun < PASS.semanticdone && !cd.isBaseInfoComplete())
+ cd.dsymbolSemantic(null);
+ if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete())
+ sym.dsymbolSemantic(null);
+
if (sym.isBaseOf(cd, poffset))
return true;
}
@@ -6355,10 +6083,9 @@ extern (C++) final class TypeTuple : Type
extern (D) this(Expressions* exps)
{
super(Ttuple);
- auto arguments = new Parameters();
+ auto arguments = new Parameters(exps ? exps.dim : 0);
if (exps)
{
- arguments.setDim(exps.dim);
for (size_t i = 0; i < exps.dim; i++)
{
Expression e = (*exps)[i];
@@ -7330,3 +7057,325 @@ const(char)* toChars(ScopeRef sr) pure nothrow @nogc @safe
return names[sr];
}
}
+
+/**
+ * Used by `callMatch` to check if the copy constructor may be called to
+ * copy the argument
+ *
+ * This is done by seeing if a call to the copy constructor can be made:
+ * ```
+ * typeof(tprm) __copytmp;
+ * copytmp.__copyCtor(arg);
+ * ```
+ */
+private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct,
+ Expression arg, Type tprm, Scope* sc, const(char)** pMessage)
+{
+ auto tmp = new VarDeclaration(arg.loc, tprm, Identifier.generateId("__copytmp"), null);
+ tmp.storage_class = STC.rvalue | STC.temp | STC.ctfe;
+ tmp.dsymbolSemantic(sc);
+ Expression ve = new VarExp(arg.loc, tmp);
+ Expression e = new DotIdExp(arg.loc, ve, Id.ctor);
+ e = new CallExp(arg.loc, e, arg);
+ //printf("e = %s\n", e.toChars());
+ if (.trySemantic(e, sc))
+ return true;
+
+ if (pMessage)
+ {
+ /* https://issues.dlang.org/show_bug.cgi?id=22202
+ *
+ * If a function was deduced by semantic on the CallExp,
+ * it means that resolveFuncCall completed succesfully.
+ * Therefore, there exists a callable copy constructor,
+ * however, it cannot be called because scope constraints
+ * such as purity, safety or nogc.
+ */
+ OutBuffer buf;
+ auto callExp = e.isCallExp();
+ if (auto f = callExp.f)
+ {
+ char[] s;
+ if (!f.isPure && sc.func.setImpure())
+ s ~= "pure ";
+ if (!f.isSafe() && !f.isTrusted() && sc.setUnsafe())
+ s ~= "@safe ";
+ if (!f.isNogc && sc.func.setGC())
+ s ~= "nogc ";
+ if (s)
+ {
+ s[$-1] = '\0';
+ buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr);
+ }
+ else if (f.isGenerated() && f.isDisabled())
+ {
+ /* https://issues.dlang.org/show_bug.cgi?id=23097
+ * Compiler generated copy constructor failed.
+ */
+ buf.printf("generating a copy constructor for `struct %s` failed, therefore instances of it are uncopyable",
+ argStruct.toChars());
+ }
+ else
+ {
+ /* Although a copy constructor may exist, no suitable match was found.
+ * i.e: `inout` constructor creates `const` object, not mutable.
+ * Fallback to using the original generic error before bugzilla 22202.
+ */
+ goto Lnocpctor;
+ }
+ }
+ else
+ {
+ Lnocpctor:
+ buf.printf("`struct %s` does not define a copy constructor for `%s` to `%s` copies",
+ argStruct.toChars(), arg.type.toChars(), tprm.toChars());
+ }
+
+ *pMessage = buf.extractChars();
+ }
+ return false;
+}
+
+/**
+ * Match a single parameter to an argument.
+ *
+ * This function is called by `TypeFunction.callMatch` while iterating over
+ * the list of parameter. Here we check if `arg` is a match for `p`,
+ * which is mostly about checking if `arg.type` converts to `p`'s type
+ * and some check about value reference.
+ *
+ * Params:
+ * tf = The `TypeFunction`, only used for error reporting
+ * p = The parameter of `tf` being matched
+ * arg = Argument being passed (bound) to `p`
+ * wildmatch = Wild (`inout`) matching level, derived from the full argument list
+ * flag = A non-zero value means we're doing a partial ordering check
+ * (no value semantic check)
+ * sc = Scope we are in
+ * pMessage = A buffer to write the error in, or `null`
+ *
+ * Returns: Whether `trailingArgs` match `p`.
+ */
+private extern(D) MATCH argumentMatchParameter (TypeFunction tf, Parameter p,
+ Expression arg, ubyte wildmatch, int flag, Scope* sc, const(char)** pMessage)
+{
+ //printf("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars());
+ MATCH m;
+ Type targ = arg.type;
+ Type tprm = wildmatch ? p.type.substWildTo(wildmatch) : p.type;
+
+ if (p.isLazy() && tprm.ty == Tvoid && targ.ty != Tvoid)
+ m = MATCH.convert;
+ else if (flag)
+ {
+ // for partial ordering, value is an irrelevant mockup, just look at the type
+ m = targ.implicitConvTo(tprm);
+ }
+ else
+ {
+ const isRef = p.isReference();
+ StructDeclaration argStruct, prmStruct;
+
+ // first look for a copy constructor
+ if (arg.isLvalue() && !isRef && targ.ty == Tstruct && tprm.ty == Tstruct)
+ {
+ // if the argument and the parameter are of the same unqualified struct type
+ argStruct = (cast(TypeStruct)targ).sym;
+ prmStruct = (cast(TypeStruct)tprm).sym;
+ }
+
+ // check if the copy constructor may be called to copy the argument
+ if (argStruct && argStruct == prmStruct && argStruct.hasCopyCtor)
+ {
+ if (!isCopyConstructorCallable(argStruct, arg, tprm, sc, pMessage))
+ return MATCH.nomatch;
+ m = MATCH.exact;
+ }
+ else
+ {
+ import dmd.dcast : cimplicitConvTo;
+ m = (sc && sc.flags & SCOPE.Cfile) ? arg.cimplicitConvTo(tprm) : arg.implicitConvTo(tprm);
+ }
+ }
+
+ // Non-lvalues do not match ref or out parameters
+ if (p.isReference())
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=13783
+ // Don't use toBasetype() to handle enum types.
+ Type ta = targ;
+ Type tp = tprm;
+ //printf("fparam[%d] ta = %s, tp = %s\n", u, ta.toChars(), tp.toChars());
+
+ if (m && !arg.isLvalue())
+ {
+ if (p.storageClass & STC.out_)
+ {
+ if (pMessage) *pMessage = tf.getParamError(arg, p);
+ return MATCH.nomatch;
+ }
+
+ if (arg.op == EXP.string_ && tp.ty == Tsarray)
+ {
+ if (ta.ty != Tsarray)
+ {
+ Type tn = tp.nextOf().castMod(ta.nextOf().mod);
+ dinteger_t dim = (cast(StringExp)arg).len;
+ ta = tn.sarrayOf(dim);
+ }
+ }
+ else if (arg.op == EXP.slice && tp.ty == Tsarray)
+ {
+ // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
+ if (ta.ty != Tsarray)
+ {
+ Type tn = ta.nextOf();
+ dinteger_t dim = (cast(TypeSArray)tp).dim.toUInteger();
+ ta = tn.sarrayOf(dim);
+ }
+ }
+ else if ((p.storageClass & STC.in_) && global.params.previewIn)
+ {
+ // Allow converting a literal to an `in` which is `ref`
+ if (arg.op == EXP.arrayLiteral && tp.ty == Tsarray)
+ {
+ Type tn = tp.nextOf();
+ dinteger_t dim = (cast(TypeSArray)tp).dim.toUInteger();
+ ta = tn.sarrayOf(dim);
+ }
+
+ // Need to make this a rvalue through a temporary
+ m = MATCH.convert;
+ }
+ else if (global.params.rvalueRefParam != FeatureState.enabled ||
+ p.storageClass & STC.out_ ||
+ !arg.type.isCopyable()) // can't copy to temp for ref parameter
+ {
+ if (pMessage) *pMessage = tf.getParamError(arg, p);
+ return MATCH.nomatch;
+ }
+ else
+ {
+ /* in functionParameters() we'll convert this
+ * rvalue into a temporary
+ */
+ m = MATCH.convert;
+ }
+ }
+
+ /* If the match is not already perfect or if the arg
+ is not a lvalue then try the `alias this` chain
+ see https://issues.dlang.org/show_bug.cgi?id=15674
+ and https://issues.dlang.org/show_bug.cgi?id=21905
+ */
+ if (ta != tp || !arg.isLvalue())
+ {
+ Type firsttab = ta.toBasetype();
+ while (1)
+ {
+ Type tab = ta.toBasetype();
+ Type tat = tab.aliasthisOf();
+ if (!tat || !tat.implicitConvTo(tprm))
+ break;
+ if (tat == tab || tat == firsttab)
+ break;
+ ta = tat;
+ }
+ }
+
+ /* A ref variable should work like a head-const reference.
+ * e.g. disallows:
+ * ref T <- an lvalue of const(T) argument
+ * ref T[dim] <- an lvalue of const(T[dim]) argument
+ */
+ if (!ta.constConv(tp))
+ {
+ if (pMessage) *pMessage = tf.getParamError(arg, p);
+ return MATCH.nomatch;
+ }
+ }
+ return m;
+}
+
+/**
+ * Match the remaining arguments `trailingArgs` with parameter `p`.
+ *
+ * Assume we already checked that `p` is the last parameter of `tf`,
+ * and we want to know whether the arguments would match `p`.
+ *
+ * Params:
+ * tf = The `TypeFunction`, only used for error reporting
+ * p = The last parameter of `tf` which is variadic
+ * trailingArgs = The remaining arguments that should match `p`
+ * pMessage = A buffer to write the error in, or `null`
+ *
+ * Returns: Whether `trailingArgs` match `p`.
+ */
+private extern(D) MATCH matchTypeSafeVarArgs(TypeFunction tf, Parameter p,
+ Expression[] trailingArgs, const(char)** pMessage)
+{
+ Type tb = p.type.toBasetype();
+
+ switch (tb.ty)
+ {
+ case Tsarray:
+ TypeSArray tsa = cast(TypeSArray)tb;
+ dinteger_t sz = tsa.dim.toInteger();
+ if (sz != trailingArgs.length)
+ {
+ if (pMessage)
+ *pMessage = tf.getMatchError("expected %llu variadic argument(s), not %zu",
+ sz, trailingArgs.length);
+ return MATCH.nomatch;
+ }
+ goto case Tarray;
+ case Tarray:
+ {
+ MATCH match = MATCH.exact;
+ TypeArray ta = cast(TypeArray)tb;
+ foreach (arg; trailingArgs)
+ {
+ MATCH m;
+ assert(arg);
+
+ /* If lazy array of delegates,
+ * convert arg(s) to delegate(s)
+ */
+ Type tret = p.isLazyArray();
+ if (tret)
+ {
+ if (ta.next.equals(arg.type))
+ m = MATCH.exact;
+ else if (tret.toBasetype().ty == Tvoid)
+ m = MATCH.convert;
+ else
+ {
+ m = arg.implicitConvTo(tret);
+ if (m == MATCH.nomatch)
+ m = arg.implicitConvTo(ta.next);
+ }
+ }
+ else
+ m = arg.implicitConvTo(ta.next);
+
+ if (m == MATCH.nomatch)
+ {
+ if (pMessage) *pMessage = tf.getParamError(arg, p);
+ return MATCH.nomatch;
+ }
+ if (m < match)
+ match = m;
+ }
+ return match;
+ }
+ case Tclass:
+ // We leave it up to the actual constructor call to do the matching.
+ return MATCH.exact;
+
+ default:
+ // We can have things as `foo(int[int] wat...)` but they only match
+ // with an associative array proper.
+ if (pMessage && trailingArgs.length) *pMessage = tf.getParamError(trailingArgs[0], p);
+ return MATCH.nomatch;
+ }
+}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 3e614d8..2b9c94c 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -221,7 +221,7 @@ public:
virtual const char *kind();
Type *copy() const;
virtual Type *syntaxCopy();
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
bool equivalent(Type *t);
// kludge for template.isType()
DYNCAST dyncast() const override final { return DYNCAST_TYPE; }
@@ -877,7 +877,7 @@ public:
static TypeTuple *create(Type *t1, Type *t2);
const char *kind() override;
TypeTuple *syntaxCopy() override;
- bool equals(const RootObject *o) const override;
+ bool equals(const RootObject * const o) const override;
void accept(Visitor *v) override { v->visit(this); }
};
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index 4f6903c..ca99b8b 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -1247,13 +1247,10 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
args2[0] = e.e2;
expandTuples(&args2);
MatchAccumulator m;
- if (s)
+ functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, &args2);
+ if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
{
- functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, &args2);
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- {
- return ErrorExp.get();
- }
+ return ErrorExp.get();
}
if (m.count > 1)
{
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index ce2769d..ed85a5d 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -2756,7 +2756,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
auto parameters = new AST.Parameters();
VarArg varargs = VarArg.none;
- int hasdefault = 0;
StorageClass varargsStc;
// Attributes allowed for ...
@@ -2921,27 +2920,23 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
//if ((storageClass & STC.scope_) && (storageClass & (STC.ref_ | STC.out_)))
//error("scope cannot be ref or out");
- if (tpl && token.value == TOK.identifier)
+ const tv = peekNext();
+ if (tpl && token.value == TOK.identifier &&
+ (tv == TOK.comma || tv == TOK.rightParenthesis || tv == TOK.dotDotDot))
{
- const tv = peekNext();
- if (tv == TOK.comma || tv == TOK.rightParenthesis || tv == TOK.dotDotDot)
- {
- Identifier id = Identifier.generateId("__T");
- const loc = token.loc;
- at = new AST.TypeIdentifier(loc, id);
- if (!*tpl)
- *tpl = new AST.TemplateParameters();
- AST.TemplateParameter tp = new AST.TemplateTypeParameter(loc, id, null, null);
- (*tpl).push(tp);
-
- ai = token.ident;
- nextToken();
- }
- else goto _else;
+ Identifier id = Identifier.generateId("__T");
+ const loc = token.loc;
+ at = new AST.TypeIdentifier(loc, id);
+ if (!*tpl)
+ *tpl = new AST.TemplateParameters();
+ AST.TemplateParameter tp = new AST.TemplateTypeParameter(loc, id, null, null);
+ (*tpl).push(tp);
+
+ ai = token.ident;
+ nextToken();
}
else
{
- _else:
at = parseType(&ai);
}
ae = null;
@@ -2949,12 +2944,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
nextToken();
ae = parseDefaultInitExp();
- hasdefault = 1;
- }
- else
- {
- if (hasdefault)
- error("default argument expected for `%s`", ai ? ai.toChars() : at.toChars());
}
auto param = new AST.Parameter(storageClass | STC.parameter, at, ai, ae, null);
if (udas)
@@ -4484,7 +4473,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
const loc = token.loc;
Identifier ident;
-
auto t = parseDeclarator(ts, alt, &ident, &tpl, storage_class, &disable, &udas);
assert(t);
if (!tfirst)
@@ -4868,6 +4856,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
token.value == TOK.identifier && peekNext() == TOK.goesTo ||
token.value == TOK.ref_ && peekNext() == TOK.leftParenthesis &&
skipAttributes(peekPastParen(peek(&token)), &tk) &&
+ (tk.value == TOK.goesTo || tk.value == TOK.leftCurly) ||
+ token.value == TOK.auto_ && peekNext() == TOK.ref_ &&
+ peekNext2() == TOK.leftParenthesis &&
+ skipAttributes(peekPastParen(peek(peek(&token))), &tk) &&
(tk.value == TOK.goesTo || tk.value == TOK.leftCurly)
)
{
@@ -4879,6 +4871,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
// identifier => expression
// ref (parameters) { statements... }
// ref (parameters) => expression
+ // auto ref (parameters) { statements... }
+ // auto ref (parameters) => expression
s = parseFunctionLiteral();
@@ -5006,7 +5000,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.delegate_:
save = token.value;
nextToken();
- if (token.value == TOK.ref_)
+ if (token.value == TOK.auto_)
+ {
+ nextToken();
+ if (token.value == TOK.ref_)
+ {
+ // function auto ref (parameters) { statements... }
+ // delegate auto ref (parameters) { statements... }
+ stc = STC.auto_ | STC.ref_;
+ nextToken();
+ }
+ else
+ error("`auto` can only be used as part of `auto ref` for function literal return values");
+ }
+ else if (token.value == TOK.ref_)
{
// function ref (parameters) { statements... }
// delegate ref (parameters) { statements... }
@@ -5034,6 +5041,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
goto case TOK.leftParenthesis;
+ case TOK.auto_:
+ {
+ nextToken();
+ if (token.value == TOK.ref_)
+ {
+ // auto ref (parameters) => expression
+ // auto ref (parameters) { statements... }
+ stc = STC.auto_ | STC.ref_;
+ nextToken();
+ }
+ else
+ error("`auto` can only be used as part of `auto ref` for function literal return values");
+ goto case TOK.leftParenthesis;
+ }
case TOK.ref_:
{
// ref (parameters) => expression
@@ -5086,7 +5107,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
auto tf = new AST.TypeFunction(parameterList, tret, linkage, stc);
tf = cast(AST.TypeFunction)tf.addSTC(stc);
- auto fd = new AST.FuncLiteralDeclaration(loc, Loc.initial, tf, save, null);
+ auto fd = new AST.FuncLiteralDeclaration(loc, Loc.initial, tf, save, null, null, stc & STC.auto_);
if (token.value == TOK.goesTo)
{
@@ -5209,7 +5230,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
else
{
- f.frequires.push(parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_));
+ auto ret = parseStatement(ParseStatementFlags.curly | ParseStatementFlags.scope_);
+ assert(ret);
+ f.frequires.push(ret);
requireDo = true;
}
goto L1;
@@ -6550,7 +6573,7 @@ LagainStc:
nextToken();
if (token.value == TOK.semicolon)
nextToken();
- s = null;
+ s = new AST.ErrorStatement;
break;
}
if (pEndloc)
@@ -8394,6 +8417,22 @@ LagainStc:
e = parseNewExp(null);
break;
+ case TOK.auto_:
+ {
+ if (peekNext() == TOK.ref_ && peekNext2() == TOK.leftParenthesis)
+ {
+ Token* tk = peekPastParen(peek(peek(&token)));
+ if (skipAttributes(tk, &tk) && (tk.value == TOK.goesTo || tk.value == TOK.leftCurly))
+ {
+ // auto ref (arguments) => expression
+ // auto ref (arguments) { statements... }
+ goto case_delegate;
+ }
+ }
+ nextToken();
+ error("found `%s` when expecting `ref` and function literal following `auto`", token.toChars());
+ goto Lerr;
+ }
case TOK.ref_:
{
if (peekNext() == TOK.leftParenthesis)
@@ -8630,7 +8669,7 @@ LagainStc:
if (token.value != TOK.identifier)
{
error("identifier expected following `(type)`.");
- return null;
+ return AST.ErrorExp.get();
}
e = new AST.DotIdExp(loc, new AST.TypeExp(loc, t), token.ident);
nextToken();
@@ -8749,7 +8788,8 @@ LagainStc:
if (peekNext() != TOK.identifier && peekNext() != TOK.new_)
{
error("identifier or new keyword expected following `(...)`.");
- return null;
+ nextToken();
+ return AST.ErrorExp.get();
}
e = new AST.TypeExp(loc, t);
e.parens = true;
diff --git a/gcc/d/dmd/root/object.h b/gcc/d/dmd/root/object.h
index 0c92a9a..b735dd9 100644
--- a/gcc/d/dmd/root/object.h
+++ b/gcc/d/dmd/root/object.h
@@ -39,7 +39,7 @@ class RootObject
public:
RootObject() { }
- virtual bool equals(const RootObject *o) const;
+ virtual bool equals(const RootObject * const o) const;
/**
* Pretty-print an Object. Useful for debugging the old-fashioned way.
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index ad4487f..d2f9c0a 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -167,11 +167,18 @@ private extern(C++) final class Semantic3Visitor : Visitor
sc = sc.push(tmix.argsym);
sc = sc.push(tmix);
+
+ uint olderrors = global.errors;
+
for (size_t i = 0; i < tmix.members.dim; i++)
{
Dsymbol s = (*tmix.members)[i];
s.semantic3(sc);
}
+
+ if (global.errors != olderrors)
+ errorSupplemental(tmix.loc, "parent scope from here: `mixin %s`", tmix.toChars());
+
sc = sc.pop();
sc.pop();
}
@@ -969,6 +976,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
/* Do the semantic analysis on the [in] preconditions and
* [out] postconditions.
*/
+ immutable bool isnothrow = f.isnothrow && !(funcdecl.flags & FUNCFLAG.nothrowInprocess);
if (freq)
{
/* frequire is composed of the [in] contracts
@@ -980,10 +988,22 @@ private extern(C++) final class Semantic3Visitor : Visitor
sc2.flags = (sc2.flags & ~SCOPE.contract) | SCOPE.require;
// BUG: need to error if accessing out parameters
- // BUG: need to disallow returns and throws
+ // BUG: need to disallow returns
// BUG: verify that all in and ref parameters are read
freq = freq.statementSemantic(sc2);
- freq.blockExit(funcdecl, false);
+
+ // @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg`
+ const blockExit = freq.blockExit(funcdecl, false);
+ if (blockExit & BE.throw_)
+ {
+ if (isnothrow)
+ // @@@DEPRECATED_2.111@@@
+ // Deprecated in 2.101, can be made an error in 2.111
+ deprecation(funcdecl.loc, "`%s`: `in` contract may throw but function is marked as `nothrow`",
+ funcdecl.toPrettyChars());
+ else if (funcdecl.flags & FUNCFLAG.nothrowInprocess)
+ f.isnothrow = false;
+ }
funcdecl.flags &= ~FUNCFLAG.noEH;
@@ -992,6 +1012,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (global.params.useIn == CHECKENABLE.off)
freq = null;
}
+
if (fens)
{
/* fensure is composed of the [out] contracts
@@ -1017,7 +1038,19 @@ private extern(C++) final class Semantic3Visitor : Visitor
funcdecl.buildResultVar(scout, f.next);
fens = fens.statementSemantic(sc2);
- fens.blockExit(funcdecl, false);
+
+ // @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg`
+ const blockExit = fens.blockExit(funcdecl, false);
+ if (blockExit & BE.throw_)
+ {
+ if (isnothrow)
+ // @@@DEPRECATED_2.111@@@
+ // Deprecated in 2.101, can be made an error in 2.111
+ deprecation(funcdecl.loc, "`%s`: `out` contract may throw but function is marked as `nothrow`",
+ funcdecl.toPrettyChars());
+ else if (funcdecl.flags & FUNCFLAG.nothrowInprocess)
+ f.isnothrow = false;
+ }
funcdecl.flags &= ~FUNCFLAG.noEH;
@@ -1144,7 +1177,6 @@ private extern(C++) final class Semantic3Visitor : Visitor
s = s.statementSemantic(sc2);
- immutable bool isnothrow = f.isnothrow && !(funcdecl.flags & FUNCFLAG.nothrowInprocess);
const blockexit = s.blockExit(funcdecl, isnothrow);
if (blockexit & BE.throw_)
{
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index 5791a88..0d7240f 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -28,6 +28,7 @@ extern(C++) class ParseTimeTransitiveVisitor(AST) : PermissiveVisitor!AST
*/
package mixin template ParseVisitMethods(AST)
{
+ import dmd.root.array;
// Statement Nodes
//===========================================================
@@ -46,7 +47,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.CompileStatement s)
{
//printf("Visiting CompileStatement\n");
- visitArgs(s.exps);
+ visitArgs(s.exps.peekSlice());
}
override void visit(AST.CompoundStatement s)
@@ -181,11 +182,9 @@ package mixin template ParseVisitMethods(AST)
s.elsebody.accept(this);
}
- void visitArgs(AST.Expressions* expressions, AST.Expression basis = null)
+ private extern(D) void visitArgs(AST.Expression[] expressions, AST.Expression basis = null)
{
- if (!expressions || !expressions.dim)
- return;
- foreach (el; *expressions)
+ foreach (el; expressions)
{
if (!el)
el = basis;
@@ -197,8 +196,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.PragmaStatement s)
{
//printf("Visiting PragmaStatement\n");
- if (s.args && s.args.dim)
- visitArgs(s.args);
+ visitArgs(s.args.peekSlice());
if (s._body)
s._body.accept(this);
}
@@ -346,19 +344,14 @@ package mixin template ParseVisitMethods(AST)
foreach (p; *td.origParameters)
p.accept(this);
}
- visitParameters(t.parameterList.parameters);
+ visitParameters(t.parameterList.parameters.peekSlice());
}
- void visitParameters(AST.Parameters* parameters)
+ private extern(D) final void visitParameters(AST.Parameter[] parameters)
{
- if (parameters)
+ foreach (i; 0 .. parameters.length)
{
- size_t dim = AST.Parameter.dim(parameters);
- foreach(i; 0..dim)
- {
- AST.Parameter fparam = AST.Parameter.getNth(parameters, i);
- fparam.accept(this);
- }
+ parameters[i].accept(this);
}
}
@@ -469,7 +462,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.TypeTuple t)
{
//printf("Visiting TypeTuple\n");
- visitParameters(t.arguments);
+ visitParameters(t.arguments.peekSlice());
}
override void visit(AST.TypeSlice t)
@@ -487,7 +480,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.TypeMixin t)
{
- visitArgs(t.exps);
+ visitArgs(t.exps.peekSlice());
}
// Miscellaneous
@@ -571,8 +564,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.PragmaDeclaration d)
{
//printf("Visiting PragmaDeclaration\n");
- if (d.args && d.args.dim)
- visitArgs(d.args);
+ visitArgs(d.args.peekSlice());
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
@@ -580,24 +572,22 @@ package mixin template ParseVisitMethods(AST)
{
//printf("Visiting ConditionalDeclaration\n");
d.condition.accept(this);
- if (d.decl)
- foreach (de; *d.decl)
- de.accept(this);
- if (d.elsedecl)
- foreach (de; *d.elsedecl)
- de.accept(this);
+ foreach (de; d.decl.peekSlice())
+ de.accept(this);
+ foreach (de; d.elsedecl.peekSlice())
+ de.accept(this);
}
override void visit(AST.CompileDeclaration d)
{
//printf("Visiting compileDeclaration\n");
- visitArgs(d.exps);
+ visitArgs(d.exps.peekSlice());
}
override void visit(AST.UserAttributeDeclaration d)
{
//printf("Visiting UserAttributeDeclaration\n");
- visitArgs(d.atts);
+ visitArgs(d.atts.peekSlice());
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
@@ -791,6 +781,15 @@ package mixin template ParseVisitMethods(AST)
s.accept(this);
}
+ override void visit(AST.UnionDeclaration d)
+ {
+ //printf("Visiting UnionDeclaration\n");
+ if (!d.members)
+ return;
+ foreach (s; *d.members)
+ s.accept(this);
+ }
+
override void visit(AST.ClassDeclaration d)
{
//printf("Visiting ClassDeclaration\n");
@@ -840,7 +839,7 @@ package mixin template ParseVisitMethods(AST)
auto tf = f.type.isTypeFunction();
if (!f.inferRetType && tf.next)
visitType(tf.next);
- visitParameters(tf.parameterList.parameters);
+ visitParameters(tf.parameterList.parameters.peekSlice());
AST.CompoundStatement cs = f.fbody.isCompoundStatement();
AST.Statement s = !cs ? f.fbody : null;
AST.ReturnStatement rs = s ? s.isReturnStatement() : null;
@@ -946,7 +945,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.ArrayLiteralExp e)
{
//printf("Visiting ArrayLiteralExp\n");
- visitArgs(e.elements, e.basis);
+ visitArgs(e.elements.peekSlice(), e.basis);
}
override void visit(AST.AssocArrayLiteralExp e)
@@ -978,8 +977,7 @@ package mixin template ParseVisitMethods(AST)
if (e.thisexp)
e.thisexp.accept(this);
visitType(e.newtype);
- if (e.arguments && e.arguments.dim)
- visitArgs(e.arguments);
+ visitArgs(e.arguments.peekSlice());
}
override void visit(AST.NewAnonClassExp e)
@@ -987,8 +985,7 @@ package mixin template ParseVisitMethods(AST)
//printf("Visiting NewAnonClassExp\n");
if (e.thisexp)
e.thisexp.accept(this);
- if (e.arguments && e.arguments.dim)
- visitArgs(e.arguments);
+ visitArgs(e.arguments.peekSlice());
if (e.cd)
e.cd.accept(this);
}
@@ -998,7 +995,7 @@ package mixin template ParseVisitMethods(AST)
//printf("Visiting TupleExp\n");
if (e.e0)
e.e0.accept(this);
- visitArgs(e.exps);
+ visitArgs(e.exps.peekSlice());
}
override void visit(AST.FuncExp e)
@@ -1056,7 +1053,7 @@ package mixin template ParseVisitMethods(AST)
override void visit(AST.MixinExp e)
{
//printf("Visiting MixinExp\n");
- visitArgs(e.exps);
+ visitArgs(e.exps.peekSlice());
}
override void visit(AST.ImportExp e)
@@ -1090,7 +1087,7 @@ package mixin template ParseVisitMethods(AST)
{
//printf("Visiting CallExp\n");
e.e1.accept(this);
- visitArgs(e.arguments);
+ visitArgs(e.arguments.peekSlice());
}
override void visit(AST.PtrExp e)
@@ -1124,7 +1121,7 @@ package mixin template ParseVisitMethods(AST)
{
//printf("Visiting ArrayExp\n");
e.e1.accept(this);
- visitArgs(e.arguments);
+ visitArgs(e.arguments.peekSlice());
}
override void visit(AST.PostExp e)
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index b21ff79..0ef7705 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -1388,6 +1388,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
// extended index), as we need to run semantic when `oidx` changes.
size_t tupleOrigIdx = size_t.max;
size_t tupleExtIdx = size_t.max;
+ bool hasDefault;
foreach (oidx, oparam, eidx, eparam; tf.parameterList)
{
// oparam (original param) will always have the default arg
@@ -1396,6 +1397,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
// position to get the offset in it later on.
if (oparam.defaultArg)
{
+ hasDefault = true;
// Get the obvious case out of the way
if (oparam is eparam)
errors |= !defaultArgSemantic(eparam, argsc);
@@ -1422,6 +1424,11 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
eparam.defaultArg = (*te.exps)[eidx - tupleExtIdx];
}
}
+ else if (hasDefault)
+ {
+ .error(loc, "default argument expected for `%s`", oparam.toChars());
+ errors = true;
+ }
// We need to know the default argument to resolve `auto ref`,
// hence why this has to take place as the very last step.
@@ -2089,10 +2096,12 @@ extern (C++) Type merge(Type type)
* loc = the location where the property is encountered
* ident = the identifier of the property
* flag = if flag & 1, don't report "not a property" error and just return NULL.
+ * src = expression for type `t` or null.
* Returns:
* expression representing the property, or null if not a property and (flag & 1)
*/
-Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier ident, int flag)
+Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier ident, int flag,
+ Expression src = null)
{
Expression visitType(Type mt)
{
@@ -2169,7 +2178,10 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
error(loc, "no property `%s` for type `%s`, perhaps `import %.*s;` is needed?", ident.toChars(), mt.toChars(), cast(int)n.length, n.ptr);
else
{
- error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
+ if (src)
+ error(loc, "no property `%s` for `%s` of type `%s`", ident.toChars(), src.toChars(), mt.toPrettyChars(true));
+ else
+ error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
if (auto dsym = mt.toDsymbol(scope_))
if (auto sym = dsym.isAggregateDeclaration())
{
@@ -4457,7 +4469,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
/************************
- * Get the the default initialization expression for a type.
+ * Get the default initialization expression for a type.
* Params:
* mt = the type for which the init expression is returned
* loc = the location where the expression needs to be evaluated
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index b0ce870..fa5ec90 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -908,21 +908,12 @@ public:
if ((postblit || destructor) && e->op != EXP::blit)
{
- /* Need to call postblit/destructor as part of assignment.
- Construction has already been handled by the front-end. */
- gcc_assert (e->op != EXP::construct);
-
- /* So we can call postblits on const/immutable objects. */
- Type *tm = etype->unSharedOf ()->mutableOf ();
- tree ti = build_typeinfo (e, tm);
-
- /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */
- result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4,
- d_array_ptr (t1),
- build_address (t2),
- d_array_length (t1), ti);
+ /* This case should have been rewritten to `_d_arraysetassign`
+ in the semantic phase. */
+ gcc_unreachable ();
}
- else if (integer_zerop (t2))
+
+ if (integer_zerop (t2))
{
tree size = size_mult_expr (d_array_length (t1),
size_int (etype->size ()));
@@ -2473,6 +2464,20 @@ public:
if (e->argprefix)
result = compound_expr (build_expr (e->argprefix), result);
}
+ else if (tb->ty == TY::Taarray)
+ {
+ /* Allocating memory for a new associative array. */
+ tree arg = build_typeinfo (e, e->newtype);
+ tree mem = build_libcall (LIBCALL_AANEW, Type::tvoidptr, 1, arg);
+
+ /* Return an associative array pointed to by MEM. */
+ tree aatype = build_ctype (tb);
+ vec <constructor_elt, va_gc> *ce = NULL;
+ CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
+
+ result = build_nop (build_ctype (e->type),
+ build_constructor (aatype, ce));
+ }
else
gcc_unreachable ();
diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def
index 282f22c..f576bef 100644
--- a/gcc/d/runtime.def
+++ b/gcc/d/runtime.def
@@ -115,10 +115,6 @@ DEF_D_RUNTIME (ALLOCMEMORY, "_d_allocmemory", RT(VOIDPTR), P1(SIZE_T),
DEF_D_RUNTIME (ARRAYCOPY, "_d_arraycopy", RT(ARRAY_VOID),
P3(SIZE_T, ARRAY_VOID, ARRAY_VOID), 0)
-/* Used for array assignments from a single element. */
-DEF_D_RUNTIME (ARRAYSETASSIGN, "_d_arraysetassign", RT(VOIDPTR),
- P4(VOIDPTR, VOIDPTR, SIZE_T, CONST_TYPEINFO), 0)
-
/* Used for concatenating two or more arrays together. Then `n' variant is
for when there is more than two arrays to handle. */
DEF_D_RUNTIME (ARRAYCATT, "_d_arraycatT", RT(ARRAY_BYTE),
@@ -140,6 +136,7 @@ DEF_D_RUNTIME (ARRAYAPPENDWD, "_d_arrayappendwd", RT(ARRAY_VOID),
/* Used for allocating a new associative array. */
DEF_D_RUNTIME (ASSOCARRAYLITERALTX, "_d_assocarrayliteralTX", RT(VOIDPTR),
P3(CONST_TYPEINFO, ARRAY_VOID, ARRAY_VOID), 0)
+DEF_D_RUNTIME (AANEW, "_aaNew", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
/* Used for value equality of two associative arrays. */
DEF_D_RUNTIME (AAEQUAL, "_aaEqual", RT(INT),
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 7df6345..cc01c69 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -4598,6 +4598,15 @@ the GCC sources.
Use the @option{--disable-sjlj-exceptions} and
@option{--enable-newlib-io-long-long} options when configuring.
+The @option{--with-arch} option may be specified to override the
+default value for the @option{-march} option, and to also build
+corresponding target libraries.
+The default is @option{--with-arch=sm_30}.
+
+For example, if @option{--with-arch=sm_70} is specified,
+@option{-march=sm_30} and @option{-march=sm_70} target libraries are
+built, and code generation defaults to @option{-march=sm_70}.
+
@html
<hr />
@end html
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 928ab0f..383d22a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -9901,7 +9901,7 @@ security-sensitive value is written to an output file
See @uref{https://cwe.mitre.org/data/definitions/532.html, CWE-532: Information Exposure Through Log Files}.
-@item Wanalyzer-exposure-through-uninit-copy
+@item -Wanalyzer-exposure-through-uninit-copy
@opindex Wanalyzer-exposure-through-uninit-copy
@opindex Wno-analyzer-exposure-through-uninit-copy
This warning requires both @option{-fanalyzer} and the use of a plugin
@@ -19681,6 +19681,9 @@ and the features that they enable by default:
@item @samp{armv8.7-a} @tab Armv8.7-A @tab @samp{armv8.6-a}, @samp{+ls64}
@item @samp{armv8.8-a} @tab Armv8.8-a @tab @samp{armv8.7-a}, @samp{+mops}
@item @samp{armv9-a} @tab Armv9-A @tab @samp{armv8.5-a}, @samp{+sve}, @samp{+sve2}
+@item @samp{armv9.1-a} @tab Armv9.1-A @tab @samp{armv9-a}, @samp{+bf16}, @samp{+i8mm}
+@item @samp{armv9.2-a} @tab Armv9.2-A @tab @samp{armv9.1-a}, @samp{+ls64}
+@item @samp{armv9.3-a} @tab Armv9.3-A @tab @samp{armv9.2-a}, @samp{+mops}
@item @samp{armv8-r} @tab Armv8-R @tab @samp{armv8-r}
@end multitable
@@ -28055,7 +28058,9 @@ supported.
Generate code for the specified PTX ISA target architecture
(e.g.@: @samp{sm_35}). Valid architecture strings are @samp{sm_30},
@samp{sm_35}, @samp{sm_53}, @samp{sm_70}, @samp{sm_75} and
-@samp{sm_80}. The default target architecture is sm_30.
+@samp{sm_80}.
+The default depends on how the compiler has been configured, see
+@option{--with-arch}.
This option sets the value of the preprocessor macro
@code{__PTX_SM__}; for instance, for @samp{sm_35}, it has the value
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 760ff95..52357cc 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2447,7 +2447,7 @@ PowerPC target pre-defines macro _ARCH_PWR9 which means the @code{-mcpu}
setting is Power9 or later.
@end table
-@subsection RISC-V specific attributes
+@subsubsection RISC-V specific attributes
@table @code
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 998fb1b..6985e62 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,69 @@
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ * trans-expr.cc (gfc_conv_procedure_call): Allow strictly
+ matching derived types.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/99169
+ * trans-expr.cc (gfc_conv_procedure_call): Remove conditions
+ on ALLOCATABLE and POINTER attributes guarding clobber
+ generation.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87401
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ disabling clobber generation for ASSOCIATE variables.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ on SAVE attribute guarding clobber generation.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ disabling clobber generation for dummy variables. Remove
+ obsolete comment.
+
+2022-09-25 Harald Anlauf <anlauf@gmx.de>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * trans-expr.cc (gfc_conv_procedure_call): Use dummy
+ information from associated_dummy if there is no information
+ from the procedure interface.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/106817
+ * trans-expr.cc (gfc_conv_procedure_call): Collect all clobbers
+ to their own separate block. Append the block of clobbers to
+ the procedure preliminary block after the argument evaluation
+ codes for all the arguments.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * trans-expr.cc (gfc_conv_procedure_call): Retrieve variable
+ from the just calculated variable reference.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ * trans.h (gfc_conv_expr_reference): Remove add_clobber
+ argument.
+ * trans-expr.cc (gfc_conv_expr_reference): Ditto. Inline code
+ depending on add_clobber and conditions controlling it ...
+ (gfc_conv_procedure_call): ... to here.
+
2022-09-22 José Rui Faustino de Sousa <jrfsousa@gmail.com>
PR fortran/100103
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 7895d03..4f3ae82 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6018,7 +6018,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_charlen cl;
gfc_expr *e;
gfc_symbol *fsym;
- stmtblock_t post;
enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
gfc_component *comp = NULL;
int arglen;
@@ -6062,7 +6061,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
info = NULL;
+ stmtblock_t post, clobbers;
gfc_init_block (&post);
+ gfc_init_block (&clobbers);
gfc_init_interface_mapping (&mapping);
if (!comp)
{
@@ -6395,7 +6396,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
&& e->symtree->n.sym->attr.pointer))
&& fsym && fsym->attr.target)
/* Make sure the function only gets called once. */
- gfc_conv_expr_reference (&parmse, e, false);
+ gfc_conv_expr_reference (&parmse, e);
else if (e->expr_type == EXPR_FUNCTION
&& e->symtree->n.sym->result
&& e->symtree->n.sym->result != e->symtree->n.sym
@@ -6502,22 +6503,55 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
else
{
- bool add_clobber;
- add_clobber = fsym && fsym->attr.intent == INTENT_OUT
- && !fsym->attr.allocatable && !fsym->attr.pointer
- && e->symtree && e->symtree->n.sym
- && !e->symtree->n.sym->attr.dimension
- && !e->symtree->n.sym->attr.pointer
- && !e->symtree->n.sym->attr.allocatable
- /* See PR 41453. */
- && !e->symtree->n.sym->attr.dummy
- /* FIXME - PR 87395 and PR 41453 */
- && e->symtree->n.sym->attr.save == SAVE_NONE
- && !e->symtree->n.sym->attr.associate_var
- && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
- && e->ts.type != BT_CLASS && !sym->attr.elemental;
-
- gfc_conv_expr_reference (&parmse, e, add_clobber);
+ gfc_conv_expr_reference (&parmse, e);
+
+ gfc_symbol *dsym = fsym;
+ gfc_dummy_arg *dummy;
+
+ /* Use associated dummy as fallback for formal
+ argument if there is no explicit interface. */
+ if (dsym == NULL
+ && (dummy = arg->associated_dummy)
+ && dummy->intrinsicness == GFC_NON_INTRINSIC_DUMMY_ARG
+ && dummy->u.non_intrinsic->sym)
+ dsym = dummy->u.non_intrinsic->sym;
+
+ if (dsym
+ && dsym->attr.intent == INTENT_OUT
+ && !dsym->attr.allocatable
+ && !dsym->attr.pointer
+ && e->expr_type == EXPR_VARIABLE
+ && e->ref == NULL
+ && e->symtree
+ && e->symtree->n.sym
+ && !e->symtree->n.sym->attr.dimension
+ && e->ts.type != BT_CHARACTER
+ && e->ts.type != BT_CLASS
+ && (e->ts.type != BT_DERIVED
+ || (dsym->ts.type == BT_DERIVED
+ && e->ts.u.derived == dsym->ts.u.derived
+ /* Types with allocatable components are
+ excluded from clobbering because we need
+ the unclobbered pointers to free the
+ allocatable components in the callee.
+ Same goes for finalizable types or types
+ with finalizable components, we need to
+ pass the unclobbered values to the
+ finalization routines.
+ For parameterized types, it's less clear
+ but they may not have a constant size
+ so better exclude them in any case. */
+ && !e->ts.u.derived->attr.alloc_comp
+ && !e->ts.u.derived->attr.pdt_type
+ && !gfc_is_finalizable (e->ts.u.derived, NULL)))
+ && !sym->attr.elemental)
+ {
+ tree var;
+ var = build_fold_indirect_ref_loc (input_location,
+ parmse.expr);
+ tree clobber = build_clobber (TREE_TYPE (var));
+ gfc_add_modify (&clobbers, var, clobber);
+ }
}
/* Catch base objects that are not variables. */
if (e->ts.type == BT_CLASS
@@ -7384,6 +7418,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
vec_safe_push (arglist, parmse.expr);
}
+ gfc_add_block_to_block (&se->pre, &clobbers);
gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
if (comp)
@@ -9484,7 +9519,7 @@ gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
values only. */
void
-gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
+gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
{
gfc_ss *ss;
tree var;
@@ -9524,16 +9559,6 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
gfc_add_block_to_block (&se->pre, &se->post);
se->expr = var;
}
- else if (add_clobber && expr->ref == NULL)
- {
- tree clobber;
- tree var;
- /* FIXME: This fails if var is passed by reference, see PR
- 41453. */
- var = expr->symtree->n.sym->backend_decl;
- clobber = build_clobber (TREE_TYPE (var));
- gfc_add_modify (&se->pre, var, clobber);
- }
return;
}
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 03d5288..bc9035c 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -499,8 +499,7 @@ tree gfc_build_compare_string (tree, tree, tree, tree, int, enum tree_code);
void gfc_conv_expr (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_val (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr);
-void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr,
- bool add_clobber = false);
+void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree);
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index d9f9aae..dc42c75 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -7631,6 +7631,7 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
incoming = build_simple_mem_ref (incoming);
}
else
+ /* Note that 'var' might be a mem ref. */
v1 = v2 = v3 = var;
/* Determine position in reduction buffer, which may be used
@@ -7659,26 +7660,28 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, setup_code,
unshare_expr (ref_to_res),
- incoming, level, op, off);
+ unshare_expr (incoming),
+ level, op, off);
tree init_call
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, init_code,
unshare_expr (ref_to_res),
- v1, level, op, off);
+ unshare_expr (v1), level, op, off);
tree fini_call
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, fini_code,
unshare_expr (ref_to_res),
- v2, level, op, off);
+ unshare_expr (v2), level, op, off);
tree teardown_call
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, teardown_code,
- ref_to_res, v3, level, op, off);
+ ref_to_res, unshare_expr (v3),
+ level, op, off);
- gimplify_assign (v1, setup_call, &before_fork);
- gimplify_assign (v2, init_call, &after_fork);
- gimplify_assign (v3, fini_call, &before_join);
- gimplify_assign (outgoing, teardown_call, &after_join);
+ gimplify_assign (unshare_expr (v1), setup_call, &before_fork);
+ gimplify_assign (unshare_expr (v2), init_call, &after_fork);
+ gimplify_assign (unshare_expr (v3), fini_call, &before_join);
+ gimplify_assign (unshare_expr (outgoing), teardown_call, &after_join);
}
/* Now stitch things together. */
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 072ebd3..fc930f4 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2951,6 +2951,15 @@ operator_bitwise_and::op1_range (irange &r, tree type,
}
if (r.undefined_p ())
set_nonzero_range_from_mask (r, type, lhs);
+
+ // For 0 = op1 & MASK, op1 is ~MASK.
+ if (lhs.zero_p () && op2.singleton_p ())
+ {
+ wide_int nz = wi::bit_not (op2.get_nonzero_bits ());
+ int_range<2> tmp (type);
+ tmp.set_nonzero_bits (nz);
+ r.intersect (tmp);
+ }
return true;
}
@@ -4612,6 +4621,15 @@ range_op_bitwise_and_tests ()
op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
ASSERT_TRUE (res == int_range<1> (integer_type_node));
+ // For 0 = x & MASK, x is ~MASK.
+ {
+ int_range<2> zero (integer_zero_node, integer_zero_node);
+ int_range<2> mask = int_range<2> (INT (7), INT (7));
+ op_bitwise_and.op1_range (res, integer_type_node, zero, mask);
+ wide_int inv = wi::shwi (~7U, TYPE_PRECISION (integer_type_node));
+ ASSERT_TRUE (res.get_nonzero_bits () == inv);
+ }
+
// (NONZERO | X) is nonzero.
i1.set_nonzero (integer_type_node);
i2.set_varying (integer_type_node);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d37e199..24f4ac5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,122 @@
+2022-09-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106656
+ * g++.dg/cpp23/feat-cxx2b.C: Adjust.
+ * g++.dg/cpp2a/feat-cxx2a.C: Likewise.
+ * g++.dg/ext/char8_t-feature-test-macro-2.C: Likewise.
+ * g++.dg/ext/char8_t-init-2.C: Likewise.
+ * g++.dg/cpp2a/char8_t3.C: New test.
+ * g++.dg/cpp2a/char8_t4.C: New test.
+
+2022-09-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106784
+ * g++.dg/ext/is_convertible3.C: New test.
+ * g++.dg/ext/is_nothrow_convertible3.C: New test.
+
+2022-09-26 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107033
+ * g++.dg/modules/partial-2.cc, g++.dg/modules/partial-2.h: New
+ files, factored out from ...
+ * g++.dg/modules/partial-2_a.C, g++.dg/modules/partial-2_b.C: ...
+ these.
+ * g++.dg/modules/partial-2_c.H: New test.
+ * g++.dg/modules/partial-2_d.C: New test.
+
+2022-09-26 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/107009
+ * gcc.dg/tree-ssa/pr107009.c: New test.
+
+2022-09-26 Jeff Law <jeffreyalaw@gmail.com>
+
+ * gcc.target/riscv/ret-1.c: New test.
+
+2022-09-26 Tobias Burnus <tobias@codesourcery.com>
+
+ PR middle-end/106982
+ * c-c++-common/goacc/reduction-7.c: New test.
+ * c-c++-common/goacc/reduction-8.c: New test.
+
+2022-09-26 Kewen Lin <linkw@linux.ibm.com>
+
+ PR target/96072
+ * gcc.target/powerpc/pr96072.c: New test.
+
+2022-09-26 Hu, Lin1 <lin1.hu@intel.com>
+
+ PR target/94962
+ * gcc.target/i386/avx256-unaligned-store-3.c: Add -mno-avx512f
+
+2022-09-26 Kewen Lin <linkw@linux.ibm.com>
+
+ PR target/100645
+ * gcc.target/powerpc/pr100645.c: New test.
+
+2022-09-26 Hongtao Liu <hongtao.liu@intel.com>
+ Liwei Xu <liwei.xu@intel.com>
+
+ * gcc.target/i386/pr53346-1.c: New test.
+ * gcc.target/i386/pr53346-2.c: New test.
+ * gcc.target/i386/pr53346-3.c: New test.
+ * gcc.target/i386/pr53346-4.c: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ * gfortran.dg/intent_optimize_10.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/99169
+ * gfortran.dg/intent_optimize_9.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87401
+ * gfortran.dg/intent_optimize_8.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * gfortran.dg/intent_optimize_7.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * gfortran.dg/intent_optimize_6.f90: New test.
+
+2022-09-25 Harald Anlauf <anlauf@gmx.de>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * gfortran.dg/intent_optimize_5.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/106817
+ * gfortran.dg/intent_optimize_4.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * gfortran.dg/intent_out_15.f90: New test.
+
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107001
+ * c-c++-common/gomp/pr107001.c: New test.
+
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/106981
+ * c-c++-common/gomp/pr106981.c: New test.
+
2022-09-23 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/c2x-complit-1.c, gcc.dg/c2x-concat-1.c,
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-7.c b/gcc/testsuite/c-c++-common/goacc/reduction-7.c
new file mode 100644
index 0000000..482b0ab
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-7.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+/* PR middle-end/106982 */
+
+long long n = 100;
+int multiplicitive_n = 128;
+
+void test1(double *rand, double *a, double *b, double *c)
+{
+#pragma acc data copyin(a[0:10*multiplicitive_n], b[0:10*multiplicitive_n]) copyout(c[0:10])
+ {
+#pragma acc parallel loop
+ for (int i = 0; i < 10; ++i)
+ {
+ double temp = 1.0;
+#pragma acc loop vector reduction(*:temp)
+ for (int j = 0; j < multiplicitive_n; ++j)
+ temp *= a[(i * multiplicitive_n) + j] + b[(i * multiplicitive_n) + j];
+ c[i] = temp;
+ }
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-8.c b/gcc/testsuite/c-c++-common/goacc/reduction-8.c
new file mode 100644
index 0000000..2c3ed49
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-8.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+/* PR middle-end/106982 */
+
+void test1(double *c)
+{
+ double reduced[5];
+#pragma acc parallel loop gang private(reduced)
+ for (int x = 0; x < 5; ++x)
+#pragma acc loop worker reduction(*:reduced)
+ for (int y = 0; y < 5; ++y) { }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/assume-1.c b/gcc/testsuite/c-c++-common/gomp/assume-1.c
new file mode 100644
index 0000000..05c64a8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assume-1.c
@@ -0,0 +1,29 @@
+void
+foo (int i, int *a)
+{
+ #pragma omp assume no_openmp, absent (target, teams) holds (i < 32U) holds (i < 32U)
+ ;
+ #pragma omp assume no_openmp_routines, contains (simd)
+ {
+ #pragma omp simd
+ for (int j = 0; j < i; j++)
+ a[j] = j;
+ }
+ #pragma omp assume no_parallelism, contains (error)
+ {
+ if (i >= 32)
+ {
+ #pragma omp error at (execution) message ("Should not happen")
+ }
+ }
+ #pragma omp assume absent (for)
+ ;
+ #pragma omp assume absent (atomic, barrier, cancel, cancellation point) absent (critical, depobj)
+ ;
+ #pragma omp assume absent (distribute, flush, loop, masked, master, nothing, ordered)
+ ;
+ #pragma omp assume absent (parallel, scan, scope, section, sections, simd, single, task)
+ ;
+ #pragma omp assume absent (taskgroup, taskloop, taskwait, taskyield)
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/assume-2.c b/gcc/testsuite/c-c++-common/gomp/assume-2.c
new file mode 100644
index 0000000..4739605
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assume-2.c
@@ -0,0 +1,46 @@
+void
+foo (int i, int *a)
+{
+ #pragma omp assume no_openmp no_openmp /* { dg-error "too many 'no_openmp' clauses" } */
+ ;
+ #pragma omp assume no_openmp_routines, no_openmp_routines /* { dg-error "too many 'no_openmp_routines' clauses" } */
+ ;
+ #pragma omp assume no_parallelism, no_parallelism /* { dg-error "too many 'no_parallelism' clauses" } */
+ ;
+ #pragma omp assume absent (target, target) /* { dg-error "'target' directive mentioned multiple times in 'absent' clauses" } */
+ ;
+ #pragma omp assume absent (target, teams) absent (teams, parallel) /* { dg-error "'teams' directive mentioned multiple times in 'absent' clauses" } */
+ ;
+ #pragma omp assume contains (cancellation point, cancellation point) /* { dg-error "'cancellation point' directive mentioned multiple times in 'contains' clauses" } */
+ ;
+ #pragma omp assume contains (target enter data, target exit data) contains (target exit data, parallel) /* { dg-error "target exit data' directive mentioned multiple times in 'contains' clauses" } */
+ ;
+ #pragma omp assume absent (target enter data, target exit data) contains (target exit data, parallel) /* { dg-error "'target exit data' directive mentioned in both 'absent' and 'contains' clauses" } */
+ ;
+ #pragma omp assume contains (target enter data, target exit data) absent (target enter data, parallel) /* { dg-error "'target enter data' directive mentioned in both 'absent' and 'contains' clauses" } */
+ ;
+ #pragma omp assume contains (declare target) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+ ;
+ #pragma omp assume absent (parallel for simd) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+ ;
+ #pragma omp assume contains (target parallel) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+ ;
+ #pragma omp assume absent (assume) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+ ;
+ #pragma omp assume absent (assumes) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+ ;
+ #pragma omp assume contains (begin assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+ ;
+ #pragma omp assume contains (end assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+ ;
+ #pragma omp assume contains (foo) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+ ;
+ #pragma omp assume absent (target enter something) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+ ;
+ #pragma omp assume foobar /* { dg-error "expected assumption clause" } */
+ ;
+ #pragma omp assume ext_GCC_foobarbaz, ext_GCC_baz (1, 12, 1 < 17), no_parallelism /* { dg-warning "unknown assumption clause 'ext_GCC_foobarbaz'" } */
+ ; /* { dg-warning "unknown assumption clause 'ext_GCC_baz'" "" { target *-*-* } .-1 } */
+ #pragma omp assume /* { dg-error "expected at least one assumption clause" } */
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/assume-3.c b/gcc/testsuite/c-c++-common/gomp/assume-3.c
new file mode 100644
index 0000000..ce38359
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assume-3.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-fno-openmp -fopenmp-simd" } */
+
+int i, j;
+
+int
+foo (void)
+{
+ j = 1;
+ return 1;
+}
+
+int
+main ()
+{
+ #pragma omp assume holds (i < 42)
+ ;
+ #pragma omp assume holds (++i == 1)
+ ;
+ if (i != 0)
+ __builtin_abort ();
+ #pragma omp assume holds (foo () == 1)
+ ;
+ if (j != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/assumes-1.c b/gcc/testsuite/c-c++-common/gomp/assumes-1.c
new file mode 100644
index 0000000..8b3fb37
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assumes-1.c
@@ -0,0 +1,26 @@
+int i;
+
+#pragma omp assumes no_openmp, absent (target, teams) holds (i < 32U) holds (i < 32U)
+void
+bar (void)
+{
+}
+
+#pragma omp assumes no_openmp_routines
+
+#pragma omp assumes no_parallelism
+
+#pragma omp assumes absent (for)
+void
+fred (void)
+{
+}
+
+#pragma omp assumes absent (atomic, barrier, cancel, cancellation point) absent (critical, depobj) \
+ absent (distribute, flush, loop, masked, master, nothing, ordered) \
+ absent (parallel, scan, scope, section, sections, simd, single, task) \
+ absent (taskgroup, taskloop, taskwait, taskyield)
+void
+foo (void)
+{
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/assumes-2.c b/gcc/testsuite/c-c++-common/gomp/assumes-2.c
new file mode 100644
index 0000000..924f323
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assumes-2.c
@@ -0,0 +1,23 @@
+#pragma omp assumes no_openmp no_openmp /* { dg-error "too many 'no_openmp' clauses" } */
+#pragma omp assumes no_openmp_routines, no_openmp_routines /* { dg-error "too many 'no_openmp_routines' clauses" } */
+#pragma omp assumes no_parallelism, no_parallelism /* { dg-error "too many 'no_parallelism' clauses" } */
+#pragma omp assumes absent (target, target) /* { dg-error "'target' directive mentioned multiple times in 'absent' clauses" } */
+#pragma omp assumes absent (target, teams) absent (teams, parallel) /* { dg-error "'teams' directive mentioned multiple times in 'absent' clauses" } */
+#pragma omp assumes contains (cancellation point, cancellation point) /* { dg-error "'cancellation point' directive mentioned multiple times in 'contains' clauses" } */
+#pragma omp assumes contains (target enter data, target exit data) contains (target exit data, parallel) /* { dg-error "target exit data' directive mentioned multiple times in 'contains' clauses" } */
+#pragma omp assumes absent (target enter data, target exit data) contains (target exit data, parallel) /* { dg-error "'target exit data' directive mentioned in both 'absent' and 'contains' clauses" } */
+#pragma omp assumes contains (target enter data, target exit data) absent (target enter data, parallel) /* { dg-error "'target enter data' directive mentioned in both 'absent' and 'contains' clauses" } */
+#pragma omp assumes contains (declare target) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+#pragma omp assumes absent (parallel for simd) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+#pragma omp assumes contains (target parallel) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+#pragma omp assumes absent (assume) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+#pragma omp assumes absent (assumes) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+#pragma omp assumes contains (begin assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+#pragma omp assumes contains (end assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+#pragma omp assumes contains (foo) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+#pragma omp assumes absent (target enter something) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+#pragma omp assumes foobar /* { dg-error "expected assumption clause" } */
+#pragma omp assumes ext_GCC_foobarbaz, ext_GCC_baz (1, 12, 1 < 17), no_parallelism /* { dg-warning "unknown assumption clause 'ext_GCC_foobarbaz'" } */
+ /* { dg-warning "unknown assumption clause 'ext_GCC_baz'" "" { target *-*-* } .-1 } */
+#pragma omp assumes /* { dg-error "expected at least one assumption clause" } */
+int i;
diff --git a/gcc/testsuite/c-c++-common/gomp/assumes-3.c b/gcc/testsuite/c-c++-common/gomp/assumes-3.c
new file mode 100644
index 0000000..0bfadac
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assumes-3.c
@@ -0,0 +1,15 @@
+#pragma omp assumes contains (simd)
+#pragma omp assumes contains (error)
+#pragma omp assumes contains (simd)
+
+void
+foo (int i, int *a)
+{
+ #pragma omp simd
+ for (int j = 0; j < i; j++)
+ a[j] = j;
+ if (i >= 32)
+ {
+ #pragma omp error at (execution) message ("Should not happen")
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/assumes-4.c b/gcc/testsuite/c-c++-common/gomp/assumes-4.c
new file mode 100644
index 0000000..6e77adb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assumes-4.c
@@ -0,0 +1,6 @@
+void
+foo (void)
+{
+ #pragma omp assumes no_openmp /* { dg-error "'#pragma omp assumes' may only be used at file scope" "" { target c } } */
+ ; /* { dg-error "'#pragma omp assumes' may only be used at file or namespace scope" "" { target c++ } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/begin-assumes-1.c b/gcc/testsuite/c-c++-common/gomp/begin-assumes-1.c
new file mode 100644
index 0000000..c3332b1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/begin-assumes-1.c
@@ -0,0 +1,46 @@
+int i;
+
+#pragma omp begin assumes no_openmp, absent (target, teams) holds (i < 32U) holds (i < 32U)
+void
+bar (void)
+{
+}
+#pragma omp end assumes
+
+#pragma omp begin assumes no_openmp_routines, contains (simd)
+void
+baz (int *a)
+{
+ #pragma omp simd
+ for (int j = 0; j < i; j++)
+ a[j] = j;
+}
+#pragma omp end assumes
+
+#pragma omp begin assumes no_parallelism, contains (error)
+void
+qux (void)
+{
+ if (i >= 32)
+ {
+ #pragma omp error at (execution) message ("Should not happen")
+ }
+}
+#pragma omp end assumes
+
+#pragma omp begin assumes absent (for)
+void
+fred (void)
+{
+}
+#pragma omp end assumes
+
+#pragma omp begin assumes absent (atomic, barrier, cancel, cancellation point) absent (critical, depobj) \
+ absent (distribute, flush, loop, masked, master, nothing, ordered) \
+ absent (parallel, scan, scope, section, sections, simd, single, task) \
+ absent (taskgroup, taskloop, taskwait, taskyield)
+void
+foo (void)
+{
+}
+#pragma omp end assumes
diff --git a/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c b/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c
new file mode 100644
index 0000000..15dae64
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c
@@ -0,0 +1,63 @@
+#pragma omp begin assumes no_openmp no_openmp /* { dg-error "too many 'no_openmp' clauses" } */
+void f1 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes no_openmp_routines, no_openmp_routines /* { dg-error "too many 'no_openmp_routines' clauses" } */
+void f2 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes no_parallelism, no_parallelism /* { dg-error "too many 'no_parallelism' clauses" } */
+void f3 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (target, target) /* { dg-error "'target' directive mentioned multiple times in 'absent' clauses" } */
+void f4 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (target, teams) absent (teams, parallel) /* { dg-error "'teams' directive mentioned multiple times in 'absent' clauses" } */
+void f5 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (cancellation point, cancellation point) /* { dg-error "'cancellation point' directive mentioned multiple times in 'contains' clauses" } */
+void f6 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (target enter data, target exit data) contains (target exit data, parallel) /* { dg-error "target exit data' directive mentioned multiple times in 'contains' clauses" } */
+void f7 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (target enter data, target exit data) contains (target exit data, parallel) /* { dg-error "'target exit data' directive mentioned in both 'absent' and 'contains' clauses" } */
+void f8 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (target enter data, target exit data) absent (target enter data, parallel) /* { dg-error "'target enter data' directive mentioned in both 'absent' and 'contains' clauses" } */
+void f9 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (declare target) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+void f10 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (parallel for simd) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+void f11 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (target parallel) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+void f12 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (assume) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+void f13 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (assumes) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+void f14 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (begin assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+void f15 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (end assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+void f16 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes contains (foo) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */
+void f17 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes absent (target enter something) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */
+void f18 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes foobar /* { dg-error "expected assumption clause" } */
+void f19 (void) {}
+#pragma omp end assumes
+#pragma omp begin assumes ext_GCC_foobarbaz, ext_GCC_baz (1, 12, 1 < 17), no_parallelism /* { dg-warning "unknown assumption clause 'ext_GCC_foobarbaz'" } */
+void f20 (void) {} /* { dg-warning "unknown assumption clause 'ext_GCC_baz'" "" { target *-*-* } .-1 } */
+#pragma omp end assumes
+#pragma omp begin assumes /* { dg-error "expected at least one assumption clause" } */
+void f21 (void) {}
+#pragma omp end assumes
diff --git a/gcc/testsuite/c-c++-common/gomp/begin-assumes-3.c b/gcc/testsuite/c-c++-common/gomp/begin-assumes-3.c
new file mode 100644
index 0000000..202d5c7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/begin-assumes-3.c
@@ -0,0 +1,2 @@
+#pragma omp begin assumes no_openmp_routines
+void foo (void); /* { dg-error "'#pragma omp begin assumes' without corresponding '#pragma omp end assumes'" } */
diff --git a/gcc/testsuite/c-c++-common/gomp/begin-assumes-4.c b/gcc/testsuite/c-c++-common/gomp/begin-assumes-4.c
new file mode 100644
index 0000000..eea6f90
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/begin-assumes-4.c
@@ -0,0 +1,2 @@
+#pragma omp end assumes /* { dg-error "'#pragma omp end assumes' without corresponding '#pragma omp begin assumes'" } */
+void foo (void);
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-6.c b/gcc/testsuite/c-c++-common/gomp/declare-target-6.c
new file mode 100644
index 0000000..586eb50
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-target-6.c
@@ -0,0 +1,2 @@
+#pragma omp end declare target /* { dg-error "'#pragma omp end declare target' without corresponding '#pragma omp declare target'" } */
+void foo (void);
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda13.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda13.C
index 962ec8d..0323a0d 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda13.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda13.C
@@ -2,4 +2,4 @@
auto l1 = []() constexpr constexpr { }; // { dg-error "duplicate" }
auto l2 = []() mutable mutable { }; // { dg-error "duplicate" }
-auto l3 = []() static { }; // { dg-error "static" }
+auto l3 = []() static { }; // { dg-error "static' only valid in lambda with" "" { target c++20_down } }
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating.h b/gcc/testsuite/g++.dg/cpp23/ext-floating.h
new file mode 100644
index 0000000..ffd9e63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating.h
@@ -0,0 +1,30 @@
+// P1467R9 - Extended floating-point types and standard names.
+
+namespace std
+{
+ #ifdef __STDCPP_FLOAT16_T__
+ using float16_t = _Float16;
+ #endif
+ #ifdef __STDCPP_FLOAT32_T__
+ using float32_t = _Float32;
+ #endif
+ #ifdef __STDCPP_FLOAT64_T__
+ using float64_t = _Float64;
+ #endif
+ #ifdef __STDCPP_FLOAT128_T__
+ using float128_t = _Float128;
+ #endif
+ #undef __STDCPP_BFLOAT16_T__
+ #ifdef __STDCPP_BFLOAT16_T__
+ using bfloat16_t = __bf16; // ???
+ #endif
+ template<typename T, T v> struct integral_constant {
+ static constexpr T value = v;
+ };
+ typedef integral_constant<bool, false> false_type;
+ typedef integral_constant<bool, true> true_type;
+ template<class T, class U>
+ struct is_same : std::false_type {};
+ template <class T>
+ struct is_same<T, T> : std::true_type {};
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating1.C b/gcc/testsuite/g++.dg/cpp23/ext-floating1.C
new file mode 100644
index 0000000..63232af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating1.C
@@ -0,0 +1,447 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target c++23 } }
+// { dg-options "" }
+
+#include "ext-floating.h"
+
+#ifdef __STRICT_ANSI__
+#undef __SIZEOF_FLOAT128__
+#endif
+
+using namespace std;
+
+static_assert (!is_same<float, double>::value);
+static_assert (!is_same<float, long double>::value);
+static_assert (!is_same<double, long double>::value);
+static_assert (is_same<decltype (0.0f), float>::value);
+static_assert (is_same<decltype (0.0F), float>::value);
+static_assert (is_same<decltype (0.0), double>::value);
+static_assert (is_same<decltype (0.0l), long double>::value);
+static_assert (is_same<decltype (0.0L), long double>::value);
+static_assert (is_same<decltype (0.0f + 0.0F), float>::value);
+static_assert (is_same<decltype (0.0F + 0.0f), float>::value);
+static_assert (is_same<decltype (0.0 + 0.0), double>::value);
+static_assert (is_same<decltype (0.0l + 0.0L), long double>::value);
+static_assert (is_same<decltype (0.0L + 0.0l), long double>::value);
+#ifdef __SIZEOF_FLOAT128__
+static_assert (is_same<decltype (0.0q), __float128>::value);
+static_assert (is_same<decltype (0.0Q), __float128>::value);
+static_assert (is_same<decltype (0.0q + 0.0q), __float128>::value);
+static_assert (is_same<decltype (0.0Q + 0.0Q), __float128>::value);
+#endif
+#ifdef __STDCPP_FLOAT16_T__
+static_assert (!is_same<float, float16_t>::value);
+static_assert (!is_same<double, float16_t>::value);
+static_assert (!is_same<long double, float16_t>::value);
+static_assert (is_same<decltype (0.0f16), float16_t>::value);
+static_assert (is_same<decltype (0.0F16), float16_t>::value);
+static_assert (is_same<decltype (0.0f16 + 0.0f16), float16_t>::value);
+static_assert (is_same<decltype (0.0F16 + 0.0F16), float16_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+static_assert (!is_same<float, float32_t>::value);
+static_assert (!is_same<double, float32_t>::value);
+static_assert (!is_same<long double, float32_t>::value);
+static_assert (!is_same<decltype (0.0f), float32_t>::value);
+static_assert (!is_same<decltype (0.0F), float32_t>::value);
+static_assert (is_same<decltype (0.0f32), float32_t>::value);
+static_assert (is_same<decltype (0.0F32), float32_t>::value);
+static_assert (!is_same<decltype (0.0f32), float>::value);
+static_assert (!is_same<decltype (0.0F32), float>::value);
+static_assert (is_same<decltype (0.0f32 + 0.0f32), float32_t>::value);
+static_assert (is_same<decltype (0.0F32 + 0.0F32), float32_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+static_assert (!is_same<float, float64_t>::value);
+static_assert (!is_same<double, float64_t>::value);
+static_assert (!is_same<long double, float64_t>::value);
+static_assert (!is_same<decltype (0.0), float64_t>::value);
+static_assert (is_same<decltype (0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64), float64_t>::value);
+static_assert (!is_same<decltype (0.0f64), double>::value);
+static_assert (!is_same<decltype (0.0F64), double>::value);
+static_assert (is_same<decltype (0.0f64 + 0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0F64), float64_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+static_assert (!is_same<float, float128_t>::value);
+static_assert (!is_same<double, float128_t>::value);
+static_assert (!is_same<long double, float128_t>::value);
+static_assert (!is_same<decltype (0.0l), float128_t>::value);
+static_assert (!is_same<decltype (0.0L), float128_t>::value);
+static_assert (is_same<decltype (0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128), float128_t>::value);
+static_assert (!is_same<decltype (0.0f128), long double>::value);
+static_assert (!is_same<decltype (0.0F128), long double>::value);
+static_assert (is_same<decltype (0.0f128 + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0F128), float128_t>::value);
+#ifdef __SIZEOF_FLOAT128__
+static_assert (!is_same<float128_t, __float128>::value);
+static_assert (!is_same<decltype (0.0q), float128_t>::value);
+static_assert (!is_same<decltype (0.0Q), float128_t>::value);
+static_assert (!is_same<decltype (0.0f128), __float128>::value);
+static_assert (!is_same<decltype (0.0F128), __float128>::value);
+#endif
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+static_assert (!is_same<float, bfloat16_t>::value);
+static_assert (!is_same<double, bfloat16_t>::value);
+static_assert (!is_same<long double, bfloat16_t>::value);
+static_assert (is_same<decltype (0.0bf16), bfloat16_t>::value);
+static_assert (is_same<decltype (0.0BF16), bfloat16_t>::value);
+static_assert (is_same<decltype (0.0bf16 + 0.0bf16), bfloat16_t>::value);
+static_assert (is_same<decltype (0.0BF16 + 0.0BF16), bfloat16_t>::value);
+#endif
+#ifdef __FLT32X_MANT_DIG__
+static_assert (!is_same<float, _Float32x>::value);
+static_assert (!is_same<double, _Float32x>::value);
+static_assert (!is_same<long double, _Float32x>::value);
+static_assert (!is_same<decltype (0.0f), _Float32x>::value);
+static_assert (!is_same<decltype (0.0F), _Float32x>::value);
+static_assert (is_same<decltype (0.0f32x), _Float32x>::value);
+static_assert (is_same<decltype (0.0F32x), _Float32x>::value);
+static_assert (!is_same<decltype (0.0f32x), float>::value);
+static_assert (!is_same<decltype (0.0F32x), float>::value);
+static_assert (is_same<decltype (0.0f32x + 0.0f32x), _Float32x>::value);
+static_assert (is_same<decltype (0.0F32x + 0.0F32x), _Float32x>::value);
+#ifdef __STDCPP_FLOAT16_T__
+static_assert (!is_same<float16_t, _Float32x>::value);
+static_assert (!is_same<decltype (0.0f16), _Float32x>::value);
+static_assert (!is_same<decltype (0.0F16), _Float32x>::value);
+static_assert (!is_same<decltype (0.0f32x), float16_t>::value);
+static_assert (!is_same<decltype (0.0F32x), float16_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+static_assert (!is_same<float32_t, _Float32x>::value);
+static_assert (!is_same<decltype (0.0f32), _Float32x>::value);
+static_assert (!is_same<decltype (0.0F32), _Float32x>::value);
+static_assert (!is_same<decltype (0.0f32x), float32_t>::value);
+static_assert (!is_same<decltype (0.0F32x), float32_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+static_assert (!is_same<float64_t, _Float32x>::value);
+static_assert (!is_same<decltype (0.0f64), _Float32x>::value);
+static_assert (!is_same<decltype (0.0F64), _Float32x>::value);
+static_assert (!is_same<decltype (0.0f32x), float64_t>::value);
+static_assert (!is_same<decltype (0.0F32x), float64_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+static_assert (!is_same<float128_t, _Float32x>::value);
+static_assert (!is_same<decltype (0.0f128), _Float32x>::value);
+static_assert (!is_same<decltype (0.0F128), _Float32x>::value);
+static_assert (!is_same<decltype (0.0f32x), float128_t>::value);
+static_assert (!is_same<decltype (0.0F32x), float128_t>::value);
+#endif
+#endif
+#ifdef __FLT64X_MANT_DIG__
+static_assert (!is_same<float, _Float64x>::value);
+static_assert (!is_same<double, _Float64x>::value);
+static_assert (!is_same<long double, _Float64x>::value);
+static_assert (!is_same<decltype (0.0), _Float64x>::value);
+static_assert (is_same<decltype (0.0f64x), _Float64x>::value);
+static_assert (is_same<decltype (0.0F64x), _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64x), double>::value);
+static_assert (!is_same<decltype (0.0F64x), double>::value);
+static_assert (is_same<decltype (0.0f64x + 0.0f64x), _Float64x>::value);
+static_assert (is_same<decltype (0.0F64x + 0.0F64x), _Float64x>::value);
+#ifdef __STDCPP_FLOAT16_T__
+static_assert (!is_same<float16_t, _Float64x>::value);
+static_assert (!is_same<decltype (0.0f16), _Float64x>::value);
+static_assert (!is_same<decltype (0.0F16), _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64x), float16_t>::value);
+static_assert (!is_same<decltype (0.0F64x), float16_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+static_assert (!is_same<float32_t, _Float64x>::value);
+static_assert (!is_same<decltype (0.0f32), _Float64x>::value);
+static_assert (!is_same<decltype (0.0F32), _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64x), float32_t>::value);
+static_assert (!is_same<decltype (0.0F64x), float32_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+static_assert (!is_same<float64_t, _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64), _Float64x>::value);
+static_assert (!is_same<decltype (0.0F64), _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64x), float64_t>::value);
+static_assert (!is_same<decltype (0.0F64x), float64_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+static_assert (!is_same<float128_t, _Float64x>::value);
+static_assert (!is_same<decltype (0.0f128), _Float64x>::value);
+static_assert (!is_same<decltype (0.0F128), _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64x), float128_t>::value);
+static_assert (!is_same<decltype (0.0F64x), float128_t>::value);
+#endif
+#ifdef __SIZEOF_FLOAT128__
+static_assert (!is_same<_Float64x, __float128>::value);
+static_assert (!is_same<decltype (0.0q), _Float64x>::value);
+static_assert (!is_same<decltype (0.0Q), _Float64x>::value);
+static_assert (!is_same<decltype (0.0f64x), __float128>::value);
+static_assert (!is_same<decltype (0.0F64x), __float128>::value);
+#endif
+#endif
+#ifdef __FLT128X_MANT_DIG__
+static_assert (!is_same<float, _Float128x>::value);
+static_assert (!is_same<double, _Float128x>::value);
+static_assert (!is_same<long double, _Float128x>::value);
+static_assert (!is_same<decltype (0.0l), _Float128x>::value);
+static_assert (!is_same<decltype (0.0L), _Float128x>::value);
+static_assert (is_same<decltype (0.0f128x), _Float128x>::value);
+static_assert (is_same<decltype (0.0F128x), _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128x), long double>::value);
+static_assert (!is_same<decltype (0.0F128x), long double>::value);
+static_assert (is_same<decltype (0.0f128x + 0.0f128x), _Float128x>::value);
+static_assert (is_same<decltype (0.0F128x + 0.0F128x), _Float128x>::value);
+#ifdef __STDCPP_FLOAT16_T__
+static_assert (!is_same<float16_t, _Float128x>::value);
+static_assert (!is_same<decltype (0.0f16), _Float128x>::value);
+static_assert (!is_same<decltype (0.0F16), _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128x), float16_t>::value);
+static_assert (!is_same<decltype (0.0F128x), float16_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+static_assert (!is_same<float32_t, _Float128x>::value);
+static_assert (!is_same<decltype (0.0f32), _Float128x>::value);
+static_assert (!is_same<decltype (0.0F32), _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128x), float32_t>::value);
+static_assert (!is_same<decltype (0.0F128x), float32_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+static_assert (!is_same<float64_t, _Float128x>::value);
+static_assert (!is_same<decltype (0.0f64), _Float128x>::value);
+static_assert (!is_same<decltype (0.0F64), _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128x), float64_t>::value);
+static_assert (!is_same<decltype (0.0F128x), float64_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+static_assert (!is_same<float128_t, _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128), _Float128x>::value);
+static_assert (!is_same<decltype (0.0F128), _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128x), float128_t>::value);
+static_assert (!is_same<decltype (0.0F128x), float128_t>::value);
+#endif
+#ifdef __SIZEOF_FLOAT128__
+static_assert (!is_same<_Float128x, __float128>::value);
+static_assert (!is_same<decltype (0.0q), _Float128x>::value);
+static_assert (!is_same<decltype (0.0Q), _Float128x>::value);
+static_assert (!is_same<decltype (0.0f128x), __float128>::value);
+static_assert (!is_same<decltype (0.0F128x), __float128>::value);
+#endif
+#endif
+static_assert (is_same<decltype (0.0f + 0.0), double>::value);
+static_assert (is_same<decltype (0.0 + 0.0F), double>::value);
+static_assert (is_same<decltype (0.0L + 0.0), long double>::value);
+static_assert (is_same<decltype (0.0 + 0.0L), long double>::value);
+static_assert (is_same<decltype (0.0L + 0.0f), long double>::value);
+static_assert (is_same<decltype (0.0F + 0.0l), long double>::value);
+#if defined(__STDCPP_FLOAT16_T__) && defined(__STDCPP_FLOAT32_T__)
+static_assert (!is_same<float16_t, float32_t>::value);
+static_assert (is_same<decltype (0.0f16 + 0.0f32), float32_t>::value);
+static_assert (is_same<decltype (0.0F32 + 0.0F16), float32_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(__STDCPP_FLOAT64_T__)
+static_assert (!is_same<float16_t, float64_t>::value);
+static_assert (is_same<decltype (0.0f16 + 0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0F16), float64_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(__STDCPP_FLOAT128_T__)
+static_assert (!is_same<float16_t, float128_t>::value);
+static_assert (is_same<decltype (0.0f16 + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0F16), float128_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(__FLT32X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f16 + 0.0f32x), _Float32x>::value);
+static_assert (is_same<decltype (0.0F32x + 0.0F16), _Float32x>::value);
+#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(__FLT64X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f16 + 0.0f64x), _Float64x>::value);
+static_assert (is_same<decltype (0.0F64x + 0.0F16), _Float64x>::value);
+#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(__FLT128X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f16 + 0.0f128x), _Float128x>::value);
+static_assert (is_same<decltype (0.0F128x + 0.0F16), _Float128x>::value);
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT64_T__)
+static_assert (!is_same<float32_t, float64_t>::value);
+static_assert (is_same<decltype (0.0f32 + 0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0F32), float64_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(__STDCPP_FLOAT128_T__)
+static_assert (!is_same<float32_t, float128_t>::value);
+static_assert (is_same<decltype (0.0f32 + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0F32), float128_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(__FLT32X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f32 + 0.0f32x), _Float32x>::value);
+static_assert (is_same<decltype (0.0F32x + 0.0F32), _Float32x>::value);
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(__FLT64X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f32 + 0.0f64x), _Float64x>::value);
+static_assert (is_same<decltype (0.0F64x + 0.0F32), _Float64x>::value);
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(__FLT128X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f32 + 0.0f128x), _Float128x>::value);
+static_assert (is_same<decltype (0.0F128x + 0.0F32), _Float128x>::value);
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(__STDCPP_FLOAT128_T__)
+static_assert (!is_same<float64_t, float128_t>::value);
+static_assert (is_same<decltype (0.0f64 + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0F64), float128_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(__FLT32X_MANT_DIG__) \
+ && __FLT64_MAX_EXP__ == __FLT32X_MAX_EXP__ \
+ && __FLT64_MANT_DIG__ == __FLT32X_MANT_DIG__
+static_assert (is_same<decltype (0.0f64 + 0.0f32x), float64_t>::value);
+static_assert (is_same<decltype (0.0F32x + 0.0F64), float64_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(__FLT64X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f64 + 0.0f64x), _Float64x>::value);
+static_assert (is_same<decltype (0.0F64x + 0.0F64), _Float64x>::value);
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(__FLT128X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f64 + 0.0f128x), _Float128x>::value);
+static_assert (is_same<decltype (0.0F128x + 0.0F64), _Float128x>::value);
+#endif
+#if defined(__STDCPP_FLOAT128_T__) && defined(__FLT32X_MANT_DIG__) \
+ && __FLT128_MAX_EXP__ >= __FLT32X_MAX_EXP__ \
+ && __FLT128_MANT_DIG__ >= __FLT32X_MANT_DIG__
+static_assert (is_same<decltype (0.0f128 + 0.0f32x), float128_t>::value);
+static_assert (is_same<decltype (0.0F32x + 0.0F128), float128_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT128_T__) && defined(__FLT64X_MANT_DIG__) \
+ && __FLT128_MAX_EXP__ >= __FLT64X_MAX_EXP__ \
+ && __FLT128_MANT_DIG__ >= __FLT64X_MANT_DIG__
+static_assert (is_same<decltype (0.0f128 + 0.0f64x), float128_t>::value);
+static_assert (is_same<decltype (0.0F64x + 0.0F128), float128_t>::value);
+#endif
+#if defined(__STDCPP_FLOAT128_T__) && defined(__FLT128X_MANT_DIG__)
+static_assert (is_same<decltype (0.0f128 + 0.0f128x), _Float128>::value);
+static_assert (is_same<decltype (0.0F128x + 0.0F128), _Float128>::value);
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(__STDCPP_FLOAT32_T__)
+static_assert (!is_same<bfloat16_t, float32_t>::value);
+static_assert (is_same<decltype (0.0bf16 + 0.0f32), float32_t>::value);
+static_assert (is_same<decltype (0.0F32 + 0.0BF16), float32_t>::value);
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(__STDCPP_FLOAT64_T__)
+static_assert (!is_same<bfloat16_t, float64_t>::value);
+static_assert (is_same<decltype (0.0bf16 + 0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0BF16), float64_t>::value);
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(__STDCPP_FLOAT128_T__)
+static_assert (!is_same<bfloat16_t, float128_t>::value);
+static_assert (is_same<decltype (0.0bf16 + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0BF16), float128_t>::value);
+#endif
+#ifdef __STDCPP_FLOAT16_T__
+#if __FLT_MAX_EXP__ > __FLT16_MAX_EXP__ && __FLT_MANT_DIG__ > __FLT16_MANT_DIG__
+static_assert (is_same<decltype (0.0f + 0.0f16), float>::value);
+static_assert (is_same<decltype (0.0F16 + 0.0F), float>::value);
+#endif
+#if __DBL_MAX_EXP__ > __FLT16_MAX_EXP__ && __DBL_MANT_DIG__ > __FLT16_MANT_DIG__
+static_assert (is_same<decltype (0.0 + 0.0f16), double>::value);
+static_assert (is_same<decltype (0.0F16 + 0.0), double>::value);
+#endif
+#if __LDBL_MAX_EXP__ > __FLT16_MAX_EXP__ && __LDBL_MANT_DIG__ > __FLT16_MANT_DIG__
+static_assert (is_same<decltype (0.0L + 0.0f16), long double>::value);
+static_assert (is_same<decltype (0.0F16 + 0.0l), long double>::value);
+#endif
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+#if __FLT_MAX_EXP__ == __FLT32_MAX_EXP__ && __FLT_MANT_DIG__ == __FLT32_MANT_DIG__
+static_assert (is_same<decltype (0.0f + 0.0f32), float32_t>::value);
+static_assert (is_same<decltype (0.0F32 + 0.0F), float32_t>::value);
+#endif
+#if __DBL_MAX_EXP__ > __FLT32_MAX_EXP__ && __DBL_MANT_DIG__ > __FLT32_MANT_DIG__
+static_assert (is_same<decltype (0.0 + 0.0f32), double>::value);
+static_assert (is_same<decltype (0.0F32 + 0.0), double>::value);
+#endif
+#if __LDBL_MAX_EXP__ > __FLT32_MAX_EXP__ && __LDBL_MANT_DIG__ > __FLT32_MANT_DIG__
+static_assert (is_same<decltype (0.0L + 0.0f32), long double>::value);
+static_assert (is_same<decltype (0.0F32 + 0.0l), long double>::value);
+#endif
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+#if __FLT_MAX_EXP__ < __FLT64_MAX_EXP__ && __FLT_MANT_DIG__ < __FLT64_MANT_DIG__
+static_assert (is_same<decltype (0.0f + 0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0F), float64_t>::value);
+#endif
+#if __DBL_MAX_EXP__ == __FLT64_MAX_EXP__ && __DBL_MANT_DIG__ == __FLT64_MANT_DIG__
+static_assert (is_same<decltype (0.0 + 0.0f64), float64_t>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0), float64_t>::value);
+#endif
+#if __LDBL_MAX_EXP__ > __FLT64_MAX_EXP__ && __LDBL_MANT_DIG__ > __FLT64_MANT_DIG__
+static_assert (is_same<decltype (0.0L + 0.0f64), long double>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0l), long double>::value);
+#endif
+#if __LDBL_MAX_EXP__ == __FLT64_MAX_EXP__ && __LDBL_MANT_DIG__ == __FLT64_MANT_DIG__ \
+ && __DBL_MAX_EXP__ == __FLT64_MAX_EXP__ && __DBL_MANT_DIG__ == __FLT64_MANT_DIG__
+// An extended floating-point type with the same set of values as more than one
+// cv-unqualified standard floating-point type has a rank equal to the rank of
+// double.
+// Then long double will have higher rank than float64_t.
+static_assert (is_same<decltype (0.0L + 0.0f64), long double>::value);
+static_assert (is_same<decltype (0.0F64 + 0.0l), long double>::value);
+#endif
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+#if __FLT_MAX_EXP__ < __FLT128_MAX_EXP__ && __FLT_MANT_DIG__ < __FLT128_MANT_DIG__
+static_assert (is_same<decltype (0.0f + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0F), float128_t>::value);
+#endif
+#if __DBL_MAX_EXP__ < __FLT128_MAX_EXP__ && __DBL_MANT_DIG__ < __FLT128_MANT_DIG__
+static_assert (is_same<decltype (0.0 + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0), float128_t>::value);
+#endif
+#if __LDBL_MAX_EXP__ <= __FLT128_MAX_EXP__ && __LDBL_MANT_DIG__ <= __FLT128_MANT_DIG__ \
+ && __LDBL_MANT_DIG__ != 106 // IBM extended long double and IEEE quad are unordered.
+static_assert (is_same<decltype (0.0L + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0l), float128_t>::value);
+#endif
+#ifdef __SIZEOF_FLOAT128__
+static_assert (is_same<decltype (0.0Q + 0.0f128), float128_t>::value);
+static_assert (is_same<decltype (0.0F128 + 0.0q), float128_t>::value);
+#endif
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+#if __FLT_MAX_EXP__ > __BFLT16_MAX_EXP__ && __FLT_MANT_DIG__ > __BFLT16_MANT_DIG__
+static_assert (is_same<decltype (0.0f + 0.0bf16), float>::value);
+static_assert (is_same<decltype (0.0BF16 + 0.0F), float>::value);
+#endif
+#if __DBL_MAX_EXP__ > __BFLT16_MAX_EXP__ && __DBL_MANT_DIG__ > __BFLT16_MANT_DIG__
+static_assert (is_same<decltype (0.0 + 0.0bf16), double>::value);
+static_assert (is_same<decltype (0.0BF16 + 0.0), double>::value);
+#endif
+#if __LDBL_MAX_EXP__ > __BFLT16_MAX_EXP__ && __LDBL_MANT_DIG__ > __BFLT16_MANT_DIG__
+static_assert (is_same<decltype (0.0L + 0.0bf16), long double>::value);
+static_assert (is_same<decltype (0.0BF16 + 0.0l), long double>::value);
+#endif
+#endif
+
+void foo (float) {}
+void foo (double) {}
+void foo (long double) {}
+#ifdef __STDCPP_FLOAT16_T__
+void foo (float16_t) {}
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+void foo (float32_t) {}
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+void foo (float64_t) {}
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+void foo (float128_t) {}
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+void foo (bfloat16_t) {}
+#endif
+#ifdef __FLT32X_MANT_DIG__
+void foo (_Float32x) {}
+#endif
+#ifdef __FLT64X_MANT_DIG__
+void foo (_Float64x) {}
+#endif
+#ifdef __FLT128X_MANT_DIG__
+void foo (_Float128x) {}
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating10.C b/gcc/testsuite/g++.dg/cpp23/ext-floating10.C
new file mode 100644
index 0000000..f5563fe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating10.C
@@ -0,0 +1,13 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do run { target { c++23 && float128_runtime } } }
+// { dg-options "" }
+// { dg-add-options float128 }
+
+#ifndef WIDTH
+#ifndef __STDCPP_FLOAT128_T__
+#error Unexpected
+#endif
+#define WIDTH 128
+#endif
+
+#include "ext-floating7.C"
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating2.C b/gcc/testsuite/g++.dg/cpp23/ext-floating2.C
new file mode 100644
index 0000000..41e9a54
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating2.C
@@ -0,0 +1,157 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target c++23 } }
+// { dg-options "" }
+
+#include "ext-floating.h"
+
+#ifdef __STRICT_ANSI__
+#undef __SIZEOF_FLOAT128__
+#endif
+
+using namespace std;
+
+float fa = 1.0f;
+float fb = (float) 1.0f;
+float fc = 1.0;
+float fd = (float) 1.0;
+float fe = 1.0L;
+float ff = (float) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+float fg = 1.0Q;
+float fh = (float) 1.0Q;
+#endif
+double da = 1.0f;
+double db = (double) 1.0f;
+double dc = 1.0;
+double dd = (double) 1.0;
+double de = 1.0L;
+double df = (double) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+double dg = 1.0Q;
+double dh = (double) 1.0Q;
+#endif
+long double lda = 1.0f;
+long double ldb = (long double) 1.0f;
+long double ldc = 1.0;
+long double ldd = (long double) 1.0;
+long double lde = 1.0L;
+long double ldf = (long double) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+long double ldg = 1.0Q;
+long double ldh = (long double) 1.0Q;
+__float128 qa = 1.0f;
+__float128 qb = (__float128) 1.0f;
+__float128 qc = 1.0;
+__float128 qd = (__float128) 1.0;
+__float128 qe = 1.0L;
+__float128 qf = (__float128) 1.0L;
+__float128 qg = 1.0Q;
+__float128 qh = (__float128) 1.0Q;
+#endif
+#ifdef __STDCPP_FLOAT16_T__
+float16_t f16a = 1.0F16;
+float16_t f16b = (float16_t) 1.0F16;
+#ifdef __STDCPP_FLOAT32_T__
+float16_t f16c = 1.0F32; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float32' with greater conversion rank" "" { target { float16 && float32 } } }
+float16_t f16d = (float16_t) 1.0F32;
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+float16_t f16e = 1.0F64; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float64' with greater conversion rank" "" { target { float16 && float64 } } }
+float16_t f16f = (float16_t) 1.0F64;
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float16_t f16g = 1.0F128; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '_Float128' with greater conversion rank" "" { target { float16 && float128 } } }
+float16_t f16h = (float16_t) 1.0F128;
+#endif
+float16_t f16j = (float16_t) 1.0f;
+float16_t f16l = (float16_t) 1.0;
+float16_t f16n = (float16_t) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+float16_t f16p = (float16_t) 1.0Q;
+#endif
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+#ifdef __STDCPP_FLOAT16_T__
+float32_t f32a = 1.0F16;
+float32_t f32b = (float32_t) 1.0F16;
+#endif
+float32_t f32c = 1.0F32;
+float32_t f32d = (float32_t) 1.0F32;
+#ifdef __STDCPP_FLOAT64_T__
+float32_t f32e = 1.0F64; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float64' with greater conversion rank" "" { target { float32 && float64 } } }
+float32_t f32f = (float32_t) 1.0F64;
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float32_t f32g = 1.0F128; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '_Float128' with greater conversion rank" "" { target { float32 && float128 } } }
+float32_t f32h = (float32_t) 1.0F128;
+#endif
+#if __FLT_MAX_EXP__ <= __FLT32_MAX_EXP__ && __FLT_MANT_DIG__ <= __FLT32_MANT_DIG__
+float32_t f32i = 1.0f;
+#endif
+float32_t f32j = (float32_t) 1.0f;
+float32_t f32l = (float32_t) 1.0;
+float32_t f32n = (float32_t) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+float32_t f32p = (float32_t) 1.0Q;
+#endif
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+#ifdef __STDCPP_FLOAT16_T__
+float64_t f64a = 1.0F16;
+float64_t f64b = (float64_t) 1.0F16;
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+float64_t f64c = 1.0F32;
+float64_t f64d = (float64_t) 1.0F32;
+#endif
+float64_t f64e = 1.0F64;
+float64_t f64f = (float64_t) 1.0F64;
+#ifdef __STDCPP_FLOAT128_T__
+float64_t f64g = 1.0F128; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '_Float128' with greater conversion rank" "" { target { float64 && float128 } } }
+float64_t f64h = (float64_t) 1.0F128;
+#endif
+#if __FLT_MAX_EXP__ <= __FLT64_MAX_EXP__ && __FLT_MANT_DIG__ <= __FLT64_MANT_DIG__
+float64_t f64i = 1.0f;
+#endif
+float64_t f64j = (float64_t) 1.0f;
+#if __DBL_MAX_EXP__ <= __FLT64_MAX_EXP__ && __DBL_MANT_DIG__ <= __FLT64_MANT_DIG__
+float64_t f64k = 1.0;
+#endif
+float64_t f64l = (float64_t) 1.0;
+float64_t f64n = (float64_t) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+float64_t f64p = (float64_t) 1.0Q;
+#endif
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+#ifdef __STDCPP_FLOAT16_T__
+float128_t f128a = 1.0F16;
+float128_t f128b = (float128_t) 1.0F16;
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+float128_t f128c = 1.0F32;
+float128_t f128d = (float128_t) 1.0F32;
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+float128_t f128e = 1.0F64;
+float128_t f128f = (float128_t) 1.0F64;
+#endif
+float128_t f128g = 1.0F128;
+float128_t f128h = (float128_t) 1.0F128;
+#if __FLT_MAX_EXP__ <= __FLT128_MAX_EXP__ && __FLT_MANT_DIG__ <= __FLT128_MANT_DIG__
+float128_t f128i = 1.0f;
+#endif
+float128_t f128j = (float128_t) 1.0f;
+#if __DBL_MAX_EXP__ <= __FLT128_MAX_EXP__ && __DBL_MANT_DIG__ <= __FLT128_MANT_DIG__
+float128_t f128k = 1.0;
+#endif
+float128_t f128l = (float128_t) 1.0;
+#if __LDBL_MAX_EXP__ <= __FLT128_MAX_EXP__ && __LDBL_MANT_DIG__ <= __FLT128_MANT_DIG__ && __LDBL_MANT_DIG__ != 106
+float128_t f128m = 1.0L;
+#endif
+float128_t f128n = (float128_t) 1.0L;
+#ifdef __SIZEOF_FLOAT128__
+float128_t f128o = 1.0Q;
+float128_t f128p = (float128_t) 1.0Q;
+#endif
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating3.C b/gcc/testsuite/g++.dg/cpp23/ext-floating3.C
new file mode 100644
index 0000000..ca9399f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating3.C
@@ -0,0 +1,134 @@
+// P1467R9 - Extended floating-point types and standard names.
+// Variant of ext-floating2.C test with x86 specific assumptions
+// about float, double, long double and existence of __float128.
+// And some further tests.
+// { dg-do compile { target { c++23 && { i?86-*-linux* x86_64-*-linux* } } } }
+// { dg-options "" }
+
+#include "ext-floating.h"
+
+#if !defined(__STDCPP_FLOAT32_T__) \
+ || !defined(__STDCPP_FLOAT64_T__) || !defined(__STDCPP_FLOAT128_T__) \
+ || __FLT_MAX_EXP__ != __FLT32_MAX_EXP__ || __FLT_MANT_DIG__ != __FLT32_MANT_DIG__ \
+ || __DBL_MAX_EXP__ != __FLT64_MAX_EXP__ || __DBL_MANT_DIG__ != __FLT64_MANT_DIG__ \
+ || __LDBL_MAX_EXP__ != __FLT128_MAX_EXP__ || __LDBL_MANT_DIG__ >= __FLT128_MANT_DIG__ \
+ || !defined(__SIZEOF_FLOAT128__)
+#error Unexpected set of floating point types
+#endif
+
+using namespace std;
+
+#ifdef __STDCPP_FLOAT16_T__
+float16_t f16i = 1.0f; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'float' with greater conversion rank" "" { target float16 } }
+float16_t f16k = 1.0; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'double' with greater conversion rank" "" { target float16 } }
+float16_t f16m = 1.0L; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'long double' with greater conversion rank" "" { target float16 } }
+float16_t f16o = 1.0Q; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '__float128' with greater conversion rank" "" { target float16 } }
+#endif
+float32_t f32i = 1.0f;
+float32_t f32k = 1.0; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'double' with greater conversion rank" }
+float32_t f32m = 1.0L; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'long double' with greater conversion rank" }
+float32_t f32o = 1.0Q; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '__float128' with greater conversion rank" }
+float64_t f64i = 1.0f;
+float64_t f64k = 1.0;
+float64_t f64m = 1.0L; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from 'long double' with greater conversion rank" }
+float64_t f64o = 1.0Q; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '__float128' with greater conversion rank" }
+float128_t f128i = 1.0f;
+float128_t f128k = 1.0;
+float128_t f128m = 1.0L;
+float128_t f128o = 1.0Q;
+
+#ifdef __STDCPP_FLOAT16_T__
+constexpr float16_t f16x = 1.0F16;
+#endif
+constexpr float32_t f32x = 2.0F32;
+constexpr float64_t f64x = 3.0F64;
+constexpr float128_t f128x = 4.0F128;
+constexpr float fx = 5.0f;
+constexpr double dx = 6.0;
+constexpr long double ldx = 7.0L;
+
+constexpr int foo (float32_t) { return 1; }
+constexpr int foo (float64_t) { return 2; }
+constexpr int bar (float) { return 3; }
+constexpr int bar (double) { return 4; }
+constexpr int bar (long double) { return 5; }
+constexpr int baz (float32_t) { return 6; }
+constexpr int baz (float64_t) { return 7; }
+constexpr int baz (float128_t) { return 8; }
+constexpr int qux (float64_t) { return 9; }
+constexpr int qux (float32_t) { return 10; }
+constexpr int fred (long double) { return 11; }
+constexpr int fred (double) { return 12; }
+constexpr int fred (float) { return 13; }
+constexpr int thud (float128_t) { return 14; }
+constexpr int thud (float64_t) { return 15; }
+constexpr int thud (float32_t) { return 16; }
+struct S {
+ constexpr operator float32_t () const { return 1.0f32; }
+ constexpr operator float64_t () const { return 2.0f64; }
+};
+struct T {
+ constexpr operator float64_t () const { return 3.0f64; }
+ constexpr operator float32_t () const { return 4.0f32; }
+};
+
+void
+test (S s, T t)
+{
+#ifdef __STDCPP_FLOAT16_T__
+ foo (float16_t (1.0)); // { dg-error "call of overloaded 'foo\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (foo (float (2.0)) == 1);
+ static_assert (foo (double (3.0)) == 2);
+ constexpr double x (s);
+ static_assert (x == 2.0);
+#ifdef __STDCPP_FLOAT16_T__
+ bar (f16x); // { dg-error "call of overloaded 'bar\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (bar (f32x) == 3);
+ static_assert (bar (f64x) == 4);
+ bar (f128x); // { dg-error "no matching function for call to 'bar\\\(const std::float128_t\\\&\\\)'" }
+ // { dg-warning "converting to 'float' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-1 }
+ // { dg-warning "converting to 'double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-2 }
+ // { dg-warning "converting to 'long double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-3 }
+ static_assert (bar (fx) == 3);
+ static_assert (bar (dx) == 4);
+ static_assert (bar (ldx) == 5);
+#ifdef __STDCPP_FLOAT16_T__
+ baz (f16x); // { dg-error "call of overloaded 'baz\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (baz (f32x) == 6);
+ static_assert (baz (f64x) == 7);
+ static_assert (baz (f128x) == 8);
+ static_assert (baz (fx) == 6);
+ static_assert (baz (dx) == 7);
+ static_assert (baz (ldx) == 8);
+#ifdef __STDCPP_FLOAT16_T__
+ qux (float16_t (1.0)); // { dg-error "call of overloaded 'qux\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (qux (float (2.0)) == 10);
+ static_assert (qux (double (3.0)) == 9);
+ constexpr double y (t);
+ static_assert (y == 3.0);
+#ifdef __STDCPP_FLOAT16_T__
+ fred (f16x); // { dg-error "call of overloaded 'fred\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (fred (f32x) == 13);
+ static_assert (fred (f64x) == 12);
+ fred (f128x); // { dg-error "no matching function for call to 'fred\\\(const std::float128_t\\\&\\\)'" }
+ // { dg-warning "converting to 'float' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-1 }
+ // { dg-warning "converting to 'double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-2 }
+ // { dg-warning "converting to 'long double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-3 }
+ static_assert (fred (fx) == 13);
+ static_assert (fred (dx) == 12);
+ static_assert (fred (ldx) == 11);
+#ifdef __STDCPP_FLOAT16_T__
+ thud (f16x); // { dg-error "call of overloaded 'thud\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (thud (f32x) == 16);
+ static_assert (thud (f64x) == 15);
+ static_assert (thud (f128x) == 14);
+ static_assert (thud (fx) == 16);
+ static_assert (thud (dx) == 15);
+ static_assert (thud (ldx) == 14);
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating4.C b/gcc/testsuite/g++.dg/cpp23/ext-floating4.C
new file mode 100644
index 0000000..1bac105
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating4.C
@@ -0,0 +1,126 @@
+// P1467R9 - Extended floating-point types and standard names.
+// Variant of ext-floating3.C test with different specific assumptions
+// about float, double, long double.
+// float, double and long double are assumed to be IEEE 754 single, double
+// and quad.
+// { dg-do compile { target { c++23 && { aarch64*-*-* powerpc64le*-*-linux* riscv*-*-* s390*-*-* sparc*-*-linux* } } } }
+// { dg-options "" }
+// { dg-additional-options "-mlong-double-128" { target s390*-*-* sparc*-*-linux* } }
+// { dg-additional-options "-mvsx -mfloat128 -mlong-double-128 -mabi=ieeelongdouble -Wno-psabi" { target powerpc64le*-*-linux* } }
+
+#include "ext-floating.h"
+
+#if !defined(__STDCPP_FLOAT32_T__) \
+ || !defined(__STDCPP_FLOAT64_T__) || !defined(__STDCPP_FLOAT128_T__) \
+ || __FLT_MAX_EXP__ != __FLT32_MAX_EXP__ || __FLT_MANT_DIG__ != __FLT32_MANT_DIG__ \
+ || __DBL_MAX_EXP__ != __FLT64_MAX_EXP__ || __DBL_MANT_DIG__ != __FLT64_MANT_DIG__ \
+ || __LDBL_MAX_EXP__ != __FLT128_MAX_EXP__ || __LDBL_MANT_DIG__ != __FLT128_MANT_DIG__
+#error Unexpected set of floating point types
+#endif
+
+using namespace std;
+
+#ifdef __STDCPP_FLOAT16_T__
+float16_t f16i = 1.0f; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'float' with greater conversion rank" "" { target float16 } }
+float16_t f16k = 1.0; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'double' with greater conversion rank" "" { target float16 } }
+float16_t f16m = 1.0L; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'long double' with greater conversion rank" "" { target float16 } }
+#endif
+float32_t f32i = 1.0f;
+float32_t f32k = 1.0; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'double' with greater conversion rank" }
+float32_t f32m = 1.0L; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'long double' with greater conversion rank" }
+float64_t f64i = 1.0f;
+float64_t f64k = 1.0;
+float64_t f64m = 1.0L; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from 'long double' with greater conversion rank" }
+float128_t f128i = 1.0f;
+float128_t f128k = 1.0;
+float128_t f128m = 1.0L;
+
+#ifdef __STDCPP_FLOAT16_T__
+constexpr float16_t f16x = 1.0F16;
+#endif
+constexpr float32_t f32x = 2.0F32;
+constexpr float64_t f64x = 3.0F64;
+constexpr float128_t f128x = 4.0F128;
+constexpr float fx = 5.0f;
+constexpr double dx = 6.0;
+constexpr long double ldx = 7.0L;
+
+constexpr int foo (float32_t) { return 1; }
+constexpr int foo (float64_t) { return 2; }
+constexpr int bar (float) { return 3; }
+constexpr int bar (double) { return 4; }
+constexpr int bar (long double) { return 5; }
+constexpr int baz (float32_t) { return 6; }
+constexpr int baz (float64_t) { return 7; }
+constexpr int baz (float128_t) { return 8; }
+constexpr int qux (float64_t) { return 9; }
+constexpr int qux (float32_t) { return 10; }
+constexpr int fred (long double) { return 11; }
+constexpr int fred (double) { return 12; }
+constexpr int fred (float) { return 13; }
+constexpr int thud (float128_t) { return 14; }
+constexpr int thud (float64_t) { return 15; }
+constexpr int thud (float32_t) { return 16; }
+struct S {
+ constexpr operator float32_t () const { return 1.0f32; }
+ constexpr operator float64_t () const { return 2.0f64; }
+};
+struct T {
+ constexpr operator float64_t () const { return 3.0f64; }
+ constexpr operator float32_t () const { return 4.0f32; }
+};
+
+void
+test (S s, T t)
+{
+#ifdef __STDCPP_FLOAT16_T__
+ foo (float16_t (1.0)); // { dg-error "call of overloaded 'foo\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (foo (float (2.0)) == 1);
+ static_assert (foo (double (3.0)) == 2);
+ constexpr double x (s);
+ static_assert (x == 2.0);
+#ifdef __STDCPP_FLOAT16_T__
+ bar (f16x); // { dg-error "call of overloaded 'bar\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (bar (f32x) == 3);
+ static_assert (bar (f64x) == 4);
+ static_assert (bar (f128x) == 5);
+ static_assert (bar (fx) == 3);
+ static_assert (bar (dx) == 4);
+ static_assert (bar (ldx) == 5);
+#ifdef __STDCPP_FLOAT16_T__
+ baz (f16x); // { dg-error "call of overloaded 'baz\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (baz (f32x) == 6);
+ static_assert (baz (f64x) == 7);
+ static_assert (baz (f128x) == 8);
+ static_assert (baz (fx) == 6);
+ static_assert (baz (dx) == 7);
+ static_assert (baz (ldx) == 8);
+#ifdef __STDCPP_FLOAT16_T__
+ qux (float16_t (1.0)); // { dg-error "call of overloaded 'qux\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (qux (float (2.0)) == 10);
+ static_assert (qux (double (3.0)) == 9);
+ constexpr double y (t);
+ static_assert (y == 3.0);
+#ifdef __STDCPP_FLOAT16_T__
+ fred (f16x); // { dg-error "call of overloaded 'fred\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (fred (f32x) == 13);
+ static_assert (fred (f64x) == 12);
+ static_assert (fred (f128x) == 11);
+ static_assert (fred (fx) == 13);
+ static_assert (fred (dx) == 12);
+ static_assert (fred (ldx) == 11);
+#ifdef __STDCPP_FLOAT16_T__
+ thud (f16x); // { dg-error "call of overloaded 'thud\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
+#endif
+ static_assert (thud (f32x) == 16);
+ static_assert (thud (f64x) == 15);
+ static_assert (thud (f128x) == 14);
+ static_assert (thud (fx) == 16);
+ static_assert (thud (dx) == 15);
+ static_assert (thud (ldx) == 14);
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating5.C b/gcc/testsuite/g++.dg/cpp23/ext-floating5.C
new file mode 100644
index 0000000..7c8bf6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating5.C
@@ -0,0 +1,13 @@
+// P1467R9 - Extended floating-point types and standard names.
+// IBM extended long double and _Float128 should have unordered conversion
+// ranks as IBM extended long double has variable precision from 53 bits
+// for denormals to more than 2150 bits for certain numbers.
+// { dg-do compile { target { c++23 && { powerpc*-*-linux* } } } }
+// { dg-require-effective-target ppc_float128_sw }
+// { dg-options "-mvsx -mfloat128 -mlong-double-128 -mabi=ibmlongdouble" }
+
+auto a = 1.0F128 + 1.0L; // { dg-error "invalid operands to binary \\\+ \\\(have '_Float128' and 'long double'\\\)" }
+auto b = 1.0L + 1.0F128; // { dg-error "invalid operands to binary \\\+ \\\(have 'long double' and '_Float128'\\\)" }
+bool c;
+auto d = c ? 1.0F128 : 1.0L; // { dg-error "operands to '\\\?:' of types '_Float128' and 'long double' have unordered conversion rank" }
+auto e = c ? 1.0L : 1.0F128; // { dg-error "operands to '\\\?:' of types 'long double' and '_Float128' have unordered conversion rank" }
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating6.C b/gcc/testsuite/g++.dg/cpp23/ext-floating6.C
new file mode 100644
index 0000000..70272a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating6.C
@@ -0,0 +1,30 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target c++23 } }
+// { dg-options "" }
+
+#include "ext-floating.h"
+
+#ifdef __STRICT_ANSI__
+#undef __SIZEOF_FLOAT128__
+#endif
+
+using namespace std;
+
+float foo (float x, float y, float z) { return x * y + z; }
+double foo (double x, double y, double z) { return x * y + z; }
+long double foo (long double x, long double y, long double z) { return x * y + z; }
+#ifdef __STDCPP_FLOAT16_T__
+float16_t foo (float16_t x, float16_t y, float16_t z) { return x * y + z; }
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+float32_t foo (float32_t x, float32_t y, float32_t z) { return x * y + z; }
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+float64_t foo (float64_t x, float64_t y, float64_t z) { return x * y + z; }
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+float128_t foo (float128_t x, float128_t y, float128_t z) { return x * y + z; }
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+bfloat16_t foo (bfloat16_t x, bfloat16_t y, bfloat16_t z) { return x * y + z; }
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating7.C b/gcc/testsuite/g++.dg/cpp23/ext-floating7.C
new file mode 100644
index 0000000..5c30a59
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating7.C
@@ -0,0 +1,119 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do run { target { c++23 && float16_runtime } } }
+// { dg-options "" }
+// { dg-add-options float16 }
+
+#ifndef WIDTH
+#ifndef __STDCPP_FLOAT16_T__
+#error Unexpected
+#endif
+#define WIDTH 16
+#endif
+
+#include <stdarg.h>
+#include "ext-floating.h"
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define TYPE CONCAT (_Float, WIDTH)
+#define CST(C) CONCAT3 (C, f, WIDTH)
+#define CSTU(C) CONCAT3 (C, F, WIDTH)
+
+extern "C" void abort ();
+
+volatile TYPE a = CST (1.0), b = CSTU (2.5), c = -CST (2.5);
+volatile TYPE a2 = CST (1.0), z = CST (0.0), nz = -CST (0.0);
+
+// These types are not subject to default argument promotions.
+
+TYPE
+vafn (TYPE arg1, ...)
+{
+ va_list ap;
+ TYPE ret;
+ va_start (ap, arg1);
+ ret = arg1 + va_arg (ap, TYPE);
+ va_end (ap);
+ return ret;
+}
+
+TYPE
+fn (TYPE arg)
+{
+ return arg / 4;
+}
+
+int
+main (void)
+{
+ volatile TYPE r;
+ r = -b;
+ if (r != c)
+ abort ();
+ r = a + b;
+ if (r != CST (3.5))
+ abort ();
+ r = a - b;
+ if (r != -CST (1.5))
+ abort ();
+ r = 2 * c;
+ if (r != -5)
+ abort ();
+ r = b * c;
+ if (r != -CST (6.25))
+ abort ();
+ r = b / (a + a);
+ if (r != CST (1.25))
+ abort ();
+ r = c * 3;
+ if (r != -CST (7.5))
+ abort ();
+ volatile int i = r;
+ if (i != -7)
+ abort ();
+ r = vafn (a, c);
+ if (r != -CST (1.5))
+ abort ();
+ r = fn (a);
+ if (r != CST (0.25))
+ abort ();
+ if ((a < b) != 1)
+ abort ();
+ if ((b < a) != 0)
+ abort ();
+ if ((a < a2) != 0)
+ abort ();
+ if ((nz < z) != 0)
+ abort ();
+ if ((a <= b) != 1)
+ abort ();
+ if ((b <= a) != 0)
+ abort ();
+ if ((a <= a2) != 1)
+ abort ();
+ if ((nz <= z) != 1)
+ abort ();
+ if ((a > b) != 0)
+ abort ();
+ if ((b > a) != 1)
+ abort ();
+ if ((a > a2) != 0)
+ abort ();
+ if ((nz > z) != 0)
+ abort ();
+ if ((a >= b) != 0)
+ abort ();
+ if ((b >= a) != 1)
+ abort ();
+ if ((a >= a2) != 1)
+ abort ();
+ if ((nz >= z) != 1)
+ abort ();
+ i = (nz == z);
+ if (i != 1)
+ abort ();
+ i = (a == b);
+ if (i != 0)
+ abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating8.C b/gcc/testsuite/g++.dg/cpp23/ext-floating8.C
new file mode 100644
index 0000000..afb74a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating8.C
@@ -0,0 +1,13 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do run { target { c++23 && float32_runtime } } }
+// { dg-options "" }
+// { dg-add-options float32 }
+
+#ifndef WIDTH
+#ifndef __STDCPP_FLOAT32_T__
+#error Unexpected
+#endif
+#define WIDTH 32
+#endif
+
+#include "ext-floating7.C"
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating9.C b/gcc/testsuite/g++.dg/cpp23/ext-floating9.C
new file mode 100644
index 0000000..f0118da
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/ext-floating9.C
@@ -0,0 +1,13 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do run { target { c++23 && float64_runtime } } }
+// { dg-options "" }
+// { dg-add-options float64 }
+
+#ifndef WIDTH
+#ifndef __STDCPP_FLOAT64_T__
+#error Unexpected
+#endif
+#define WIDTH 64
+#endif
+
+#include "ext-floating7.C"
diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
index d3e4072..2f6b21e 100644
--- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
+++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
@@ -504,8 +504,8 @@
#ifndef __cpp_char8_t
# error "__cpp_char8_t"
-#elif __cpp_char8_t != 201811
-# error "__cpp_char8_t != 201811"
+#elif __cpp_char8_t != 202207
+# error "__cpp_char8_t != 202207"
#endif
#ifndef __cpp_designated_initializers
@@ -563,3 +563,9 @@
#elif __cpp_named_character_escapes != 202207
# error "__cpp_named_character_escapes != 202207"
#endif
+
+#ifndef __cpp_static_call_operator
+# error "__cpp_static_call_operator"
+#elif __cpp_static_call_operator != 202207
+# error "__cpp_static_call_operator != 202207"
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call1.C b/gcc/testsuite/g++.dg/cpp23/static-operator-call1.C
new file mode 100644
index 0000000..42219bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call1.C
@@ -0,0 +1,41 @@
+// P1169R4 - static operator()
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template <typename T>
+struct S
+{
+ static constexpr bool operator () (T const &x, T const &y) { return x < y; }; // { dg-warning "may be a static member function only with" "" { target c++20_down } }
+ using P = bool (*) (T const &, T const &);
+ operator P () const { return operator (); }
+};
+
+static_assert (S<int> {} (1, 2), "");
+
+template <typename T>
+void
+bar (T &x)
+{
+ x (1, 2);
+}
+
+void
+foo ()
+{
+#if __cpp_constexpr >= 201603L
+ auto a = [](int x, int y) static constexpr { return x + y; }; // { dg-warning "'static' only valid in lambda with" "" { target { c++17 && c++20_down } } }
+ static_assert (a (1, 2) == 3, "");
+ bar (*a);
+#endif
+ auto b = []() static { return 1; }; // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } }
+ b ();
+ auto c = [](int x, int y) static { return x + y; }; // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } }
+ c (1, 2);
+ bar (*c);
+#if __cpp_generic_lambdas >= 201707L
+ auto d = []<typename T, typename U>(T x, U y) static { return x + y; }; // { dg-warning "'static' only valid in lambda with" "" { target c++20_only } }
+ d (1, 2L);
+#endif
+ S<long> s;
+ s(1L, 2L);
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call2.C b/gcc/testsuite/g++.dg/cpp23/static-operator-call2.C
new file mode 100644
index 0000000..21f3d44
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call2.C
@@ -0,0 +1,22 @@
+// P1169R4 - static operator()
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+void
+foo ()
+{
+ int u = 0;
+ auto a = [](int x, int y) mutable mutable { return x + y; }; // { dg-error "duplicate 'mutable' specifier" }
+ auto b = [](int x, int y) static static { return x + y; }; // { dg-error "duplicate 'static' specifier" }
+ // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } .-1 }
+ auto c = [](int x, int y) static mutable { return x + y; }; // { dg-error "'mutable' specifier conflicts with 'static'" }
+ // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } .-1 }
+ auto d = [](int x, int y) mutable static { return x + y; }; // { dg-error "'static' specifier conflicts with 'mutable'" }
+ // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } .-1 }
+ auto e = [=](int x, int y) static { return x + y; }; // { dg-error "lambda specifier with lambda capture" }
+ // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } .-1 }
+ auto f = [&](int x, int y) static { return x + y; }; // { dg-error "lambda specifier with lambda capture" }
+ // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } .-1 }
+ auto g = [u](int x, int y) static { return x + y; }; // { dg-error "lambda specifier with lambda capture" }
+ // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } .-1 }
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/static-operator-call3.C b/gcc/testsuite/g++.dg/cpp23/static-operator-call3.C
new file mode 100644
index 0000000..9c84db6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/static-operator-call3.C
@@ -0,0 +1,10 @@
+// P1169R4 - static operator()
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+void
+foo ()
+{
+ auto a = [] (auto x) static { return x; }; // { dg-warning "'static' only valid in lambda with" "" { target c++20_down } }
+ int (*b) (int) = a;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t3.C b/gcc/testsuite/g++.dg/cpp2a/char8_t3.C
new file mode 100644
index 0000000..071a718
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/char8_t3.C
@@ -0,0 +1,37 @@
+// PR c++/106656 - P2513 - char8_t Compatibility and Portability Fixes
+// { dg-do compile { target c++20 } }
+
+const char *p1 = u8""; // { dg-error "invalid conversion" }
+const unsigned char *p2 = u8""; // { dg-error "invalid conversion" }
+const signed char *p3 = u8""; // { dg-error "invalid conversion" }
+const char *p4 = { u8"" }; // { dg-error "invalid conversion" }
+const unsigned char *p5 = { u8"" }; // { dg-error "invalid conversion" }
+const signed char *p6 = { u8"" }; // { dg-error "invalid conversion" }
+const char *p7 = static_cast<const char *>(u8""); // { dg-error "invalid" }
+const char a1[] = u8"text";
+const unsigned char a2[] = u8"";
+const signed char a3[] = u8""; // { dg-error "cannot initialize array" }
+const char a4[] = { u8"text" };
+const unsigned char a5[] = { u8"" };
+const signed char a6[] = { u8"" }; // { dg-error "cannot initialize array" }
+
+const char *
+resource_id ()
+{
+ static const char res_id[] = u8"";
+ return res_id;
+}
+
+const char8_t x[] = "fail"; // { dg-error "cannot initialize array" }
+
+void fn (const char a[]);
+void
+g ()
+{
+ fn (u8"z"); // { dg-error "invalid conversion" }
+}
+
+char c = u8'c';
+unsigned char uc = u8'c';
+signed char sc = u8'c';
+char8_t c8 = 'c';
diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t4.C b/gcc/testsuite/g++.dg/cpp2a/char8_t4.C
new file mode 100644
index 0000000..c18081b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/char8_t4.C
@@ -0,0 +1,17 @@
+// PR c++/106656 - P2513 - char8_t Compatibility and Portability Fixes
+// { dg-do compile { target c++20 } }
+// [diff.cpp20.dcl]
+
+struct A {
+ char8_t s[10];
+};
+struct B {
+ char s[10];
+};
+
+void f(A);
+void f(B);
+
+int main() {
+ f({u8""}); // { dg-error "ambiguous" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit3.C b/gcc/testsuite/g++.dg/cpp2a/constinit3.C
index a29c594..ffa6184 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constinit3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit3.C
@@ -5,7 +5,7 @@ constinit constinit int v1; // { dg-error "duplicate .constinit." }
constexpr constinit int v2 = 1; // { dg-error "can use at most one of the .constinit. and .constexpr. specifiers" }
constinit constexpr int v3 = 1; // { dg-error "an use at most one of the .constinit. and .constexpr. specifiers" }
-extern static constinit int v4; // { dg-error "conflicting specifiers" }
+extern static constinit int v4; // { dg-error "'static' specifier conflicts with 'extern'" }
extern thread_local constinit int v5;
extern constinit int v6;
diff --git a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
index c65ea6b..02f3a37 100644
--- a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
+++ b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
@@ -504,8 +504,8 @@
#ifndef __cpp_char8_t
# error "__cpp_char8_t"
-#elif __cpp_char8_t != 201811
-# error "__cpp_char8_t != 201811"
+#elif __cpp_char8_t != 202207
+# error "__cpp_char8_t != 202207"
#endif
#ifndef __cpp_designated_initializers
diff --git a/gcc/testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C b/gcc/testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C
index 1a8ac02..89e2ebd 100644
--- a/gcc/testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C
@@ -1 +1 @@
-static typedef int i __attribute__((unused)); // { dg-error "1:conflicting specifiers" }
+static typedef int i __attribute__((unused)); // { dg-error "8:'typedef' specifier conflicts with 'static'" }
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
index df1063f..2d0f904 100644
--- a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
+++ b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
@@ -5,6 +5,6 @@
#if !defined(__cpp_char8_t)
# error __cpp_char8_t is not defined!
-#elif __cpp_char8_t != 201811
-# error __cpp_char8_t != 201811
+#elif __cpp_char8_t != 202207
+# error __cpp_char8_t != 202207
#endif
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
index c713bc1..02a96ff 100644
--- a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
+++ b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
@@ -21,7 +21,7 @@ const char8_t (&rca4)[2] = u8"x";
const char8_t (&rca5)[2] = u"x"; // { dg-error "invalid initialization of reference of type .const char8_t ....... from expression of type .const char16_t ...." "char8_t" }
char ca1[] = "x";
-char ca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
+char ca2[] = u8"x";
char8_t ca3[] = "x"; // { dg-error "from a string literal with type array of .char." "char8_t" }
char8_t ca4[] = u8"x";
char8_t ca5[] = u"x"; // { dg-error "from a string literal with type array of .char16_t." "char8_t" }
@@ -30,4 +30,4 @@ signed char sca1[] = "x";
signed char sca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
unsigned char uca1[] = "x";
-unsigned char uca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
+unsigned char uca2[] = u8"x";
diff --git a/gcc/testsuite/g++.dg/ext/is_convertible3.C b/gcc/testsuite/g++.dg/ext/is_convertible3.C
new file mode 100644
index 0000000..7a986d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_convertible3.C
@@ -0,0 +1,9 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+// Make sure we don't reject this at runtime by trying to instantiate
+// something that would be ill-formed.
+
+struct A;
+struct B { template<class T> B(const T&) noexcept { T::nonexistent; } };
+
+static_assert(__is_convertible(const A&, B), "");
diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C
new file mode 100644
index 0000000..05b1e1d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C
@@ -0,0 +1,9 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+// Make sure we don't reject this at runtime by trying to instantiate
+// something that would be ill-formed.
+
+struct A;
+struct B { template<class T> B(const T&) noexcept { T::nonexistent; } };
+
+static_assert(__is_nothrow_convertible(const A&, B), "");
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-1.C b/gcc/testsuite/g++.dg/gomp/attrs-1.C
index 3f366ae..dd33b07 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-1.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-1.C
@@ -123,7 +123,7 @@ baz (int d, int m, int i1, int i2, int p, int *idp, int s,
void
bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int hda, int s,
int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm,
- const char *msg)
+ const char *msg, int n1, int n2)
{
[[omp::directive (nothing)]];
[[omp::directive (error at (execution) severity (warning) message (msg))]];
@@ -612,6 +612,19 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int hda, int s,
;
[[omp::directive (parallel)]]
switch (0) { case 1: break; default: break; }
+ [[omp::directive (assume no_openmp no_openmp_routines no_parallelism
+ absent (atomic, barrier, cancel, cancellation point)
+ absent (critical, depobj)
+ absent (distribute, flush, loop, masked, master, nothing, ordered)
+ absent (parallel, scan, scope, section, sections, simd, single, task)
+ absent (taskgroup, taskloop, taskwait, taskyield)
+ absent (target, teams, for, error) holds (n1 < n2))]]
+ if (0)
+ ;
+ [[omp::sequence (omp::directive (assume contains (simd)),
+ omp::directive (for simd))]]
+ for (int i = 0; i < 64; i++)
+ ;
}
void corge1 ();
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-15.C b/gcc/testsuite/g++.dg/gomp/attrs-15.C
new file mode 100644
index 0000000..d0598f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/attrs-15.C
@@ -0,0 +1,41 @@
+// { dg-do compile { target c++11 } }
+
+#pragma omp begin assumes absent (target)
+#pragma omp begin assumes absent (target)
+[[omp::directive (begin assumes absent (target))]];
+int a;
+[[omp::directive (end assumes)]];
+#pragma omp end assumes
+#pragma omp end assumes
+[[omp::directive (begin assumes absent (target))]];
+int b;
+#pragma omp end assumes // { dg-error "'begin assumes' in attribute syntax terminated with 'end assumes' in pragma syntax" }
+#pragma omp begin assumes absent (target)
+int c;
+[[omp::directive (end assumes)]];// { dg-error "'begin assumes' in pragma syntax terminated with 'end assumes' in attribute syntax" }
+#pragma omp begin assumes absent (target)
+[[omp::directive (begin assumes absent (target))]];
+int d;
+#pragma omp end assumes // { dg-error "'begin assumes' in attribute syntax terminated with 'end assumes' in pragma syntax" }
+#pragma omp begin assumes absent (target)
+int e;
+[[omp::directive (end assumes)]];// { dg-error "'begin assumes' in pragma syntax terminated with 'end assumes' in attribute syntax" }
+#pragma omp end assumes
+[[omp::directive (begin assumes absent (target))]];
+[[omp::directive (begin assumes absent (target))]];
+int f;
+#pragma omp end assumes // { dg-error "'begin assumes' in attribute syntax terminated with 'end assumes' in pragma syntax" }
+#pragma omp begin assumes absent (target)
+int g;
+[[omp::directive (end assumes)]];// { dg-error "'begin assumes' in pragma syntax terminated with 'end assumes' in attribute syntax" }
+[[omp::directive (end assumes)]];
+[[omp::directive (begin assumes absent (target))]];
+#pragma omp begin assumes absent (target)
+int h;
+#pragma omp end assumes
+#pragma omp end assumes // { dg-error "'begin assumes' in attribute syntax terminated with 'end assumes' in pragma syntax" }
+#pragma omp begin assumes absent (target)
+[[omp::directive (begin assumes absent (target))]];
+int i;
+[[omp::directive (end assumes)]];
+[[omp::directive (end assumes)]];// { dg-error "'begin assumes' in pragma syntax terminated with 'end assumes' in attribute syntax" }
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-16.C b/gcc/testsuite/g++.dg/gomp/attrs-16.C
new file mode 100644
index 0000000..5c1dcc5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/attrs-16.C
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++11 } }
+
+int i;
+
+[[omp::directive (assumes no_openmp, absent (target, teams) holds (i < 32U) holds (i < 32U))]];
+void
+bar (void)
+{
+}
+
+[[omp::directive (assumes no_openmp_routines)]];
+[[omp::directive (assumes no_parallelism)]];
+[[omp::directive (assumes absent (for))]];
+void
+fred (void)
+{
+}
+
+[[omp::directive (assumes absent (atomic, barrier, cancel, cancellation point) absent (critical, depobj)
+ absent (distribute, flush, loop, masked, master, nothing, ordered)
+ absent (parallel, scan, scope, section, sections, simd, single, task)
+ absent (taskgroup, taskloop, taskwait, taskyield))]];
+void
+foo (void)
+{
+}
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-17.C b/gcc/testsuite/g++.dg/gomp/attrs-17.C
new file mode 100644
index 0000000..fe36146
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/attrs-17.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++11 } }
+
+[[omp::directive (assumes contains (simd))]];
+[[omp::directive (assumes contains (error))]];
+[[omp::directive (assumes, contains (simd))]];
+
+void
+foo (int i, int *a)
+{
+ [[omp::directive (simd)]]
+ for (int j = 0; j < i; j++)
+ a[j] = j;
+ if (i >= 32)
+ {
+ [[omp::directive (error at (execution) message ("Should not happen"))]];
+ }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-2.C b/gcc/testsuite/g++.dg/gomp/attrs-2.C
index cb80415..7258d38 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-2.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-2.C
@@ -123,7 +123,7 @@ baz (int d, int m, int i1, int i2, int p, int *idp, int s,
void
bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int hda, int s,
int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm,
- const char *msg)
+ const char *msg, int n1, int n2)
{
[[omp::directive (nothing)]];
[[omp::directive (error, at (execution), severity (warning), message (msg))]];
@@ -604,6 +604,19 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int hda, int s,
extern int t2;
[[omp::directive (declare reduction (dr: int: omp_out += omp_in),initializer (omp_priv = 0))]]
;
+ [[omp::directive (assume, no_openmp, no_openmp_routines, no_parallelism,
+ absent (atomic, barrier, cancel, cancellation point),
+ absent (critical, depobj),
+ absent (distribute, flush, loop, masked, master, nothing, ordered),
+ absent (parallel, scan, scope, section, sections, simd, single, task),
+ absent (taskgroup, taskloop, taskwait, taskyield),
+ absent (target, teams, for, error), holds (n1 < n2))]]
+ if (0)
+ ;
+ [[omp::sequence (omp::directive (assume, contains (simd)),
+ omp::directive (for simd))]]
+ for (int i = 0; i < 64; i++)
+ ;
}
void corge1 ();
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-9.C b/gcc/testsuite/g++.dg/gomp/attrs-9.C
index 19a3b0a..fa02299 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-9.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-9.C
@@ -1,5 +1,6 @@
// { dg-do compile { target c++11 } }
+int n1 = 0, n2 = 42;
[[omp::sequence (directive (requires, atomic_default_mem_order (seq_cst)))]];
[[omp::directive (declare reduction (plus: int: omp_out += omp_in) initializer (omp_priv = 0))]];
int a;
@@ -14,3 +15,22 @@ int d;
[[omp::directive (end declare target)]];
[[omp::directive (end declare target)]];
[[omp::directive (nothing)]];
+[[omp::directive (begin assumes no_openmp no_openmp_routines no_parallelism
+ absent (atomic, barrier, cancel, cancellation point)
+ absent (critical, depobj)
+ absent (distribute, flush, loop, masked, master, nothing, ordered)
+ absent (parallel, scan, scope, section, sections, simd, single, task)
+ absent (taskgroup, taskloop, taskwait, taskyield)
+ absent (target, teams, for, error) holds (n1 < n2))]];
+void foo (void) {}
+[[omp::directive (end assumes)]];
+[[omp::directive (begin assumes, no_openmp, no_openmp_routines, no_parallelism,
+ absent (atomic, barrier, cancel, cancellation point),
+ absent (critical, depobj),
+ absent (distribute, flush, loop, masked, master, nothing, ordered),
+ absent (parallel, scan, scope, section, sections, simd, single, task),
+ absent (taskgroup, taskloop, taskwait, taskyield),
+ absent (target, teams, for, error), holds (n1 < n2))]];
+[[omp::directive (begin assumes no_openmp)]];
+void bar (void) {}
+[[omp::sequence (omp::directive (end assumes), omp::directive (end assumes))]];
diff --git a/gcc/testsuite/g++.dg/modules/partial-2.cc b/gcc/testsuite/g++.dg/modules/partial-2.cc
new file mode 100644
index 0000000..1316bf5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2.cc
@@ -0,0 +1,17 @@
+static_assert(is_reference_v<int&>);
+static_assert(is_reference_v<int&&>);
+static_assert(!is_reference_v<int>);
+
+static_assert(A::is_reference_v<long&>);
+static_assert(A::is_reference_v<long&&>);
+static_assert(!A::is_reference_v<long>);
+
+#if __cpp_concepts
+static_assert(concepts::is_reference_v<char&>);
+static_assert(concepts::is_reference_v<char&&>);
+static_assert(!concepts::is_reference_v<char>);
+
+static_assert(concepts::A::is_reference_v<bool&>);
+static_assert(concepts::A::is_reference_v<bool&&>);
+static_assert(!concepts::A::is_reference_v<bool>);
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2.h b/gcc/testsuite/g++.dg/modules/partial-2.h
new file mode 100644
index 0000000..afcfce7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2.h
@@ -0,0 +1,38 @@
+template<class T> constexpr bool is_reference_v = false;
+template<class T> constexpr bool is_reference_v<T&> = true;
+template<class T> constexpr bool is_reference_v<T&&> = true;
+
+struct A {
+ template<class T> static constexpr bool is_reference_v = false;
+};
+
+template<class T> constexpr bool A::is_reference_v<T&> = true;
+template<class T> constexpr bool A::is_reference_v<T&&> = true;
+
+#if __cpp_concepts
+namespace concepts {
+ template<class T> bool is_reference_v;
+
+ template<class T> requires __is_same(T, T&)
+ constexpr bool is_reference_v<T> = true;
+
+ template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+ constexpr bool is_reference_v<T> = true;
+
+ template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+ constexpr bool is_reference_v<T> = false;
+
+ struct A {
+ template<class T> static bool is_reference_v;
+ };
+
+ template<class T> requires __is_same(T, T&)
+ constexpr bool A::is_reference_v<T> = true;
+
+ template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+ constexpr bool A::is_reference_v<T> = true;
+
+ template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+ constexpr bool A::is_reference_v<T> = false;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_a.C b/gcc/testsuite/g++.dg/modules/partial-2_a.C
index 2681bb5..1582f56 100644
--- a/gcc/testsuite/g++.dg/modules/partial-2_a.C
+++ b/gcc/testsuite/g++.dg/modules/partial-2_a.C
@@ -3,41 +3,4 @@
// { dg-module-cmi pr106826 }
export module pr106826;
-template<class T> constexpr bool is_reference_v = false;
-template<class T> constexpr bool is_reference_v<T&> = true;
-template<class T> constexpr bool is_reference_v<T&&> = true;
-
-struct A {
- template<class T> static constexpr bool is_reference_v = false;
-};
-
-template<class T> constexpr bool A::is_reference_v<T&> = true;
-template<class T> constexpr bool A::is_reference_v<T&&> = true;
-
-#if __cpp_concepts
-namespace concepts {
- template<class T> bool is_reference_v;
-
- template<class T> requires __is_same(T, T&)
- constexpr bool is_reference_v<T> = true;
-
- template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
- constexpr bool is_reference_v<T> = true;
-
- template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
- constexpr bool is_reference_v<T> = false;
-
- struct A {
- template<class T> static bool is_reference_v;
- };
-
- template<class T> requires __is_same(T, T&)
- constexpr bool A::is_reference_v<T> = true;
-
- template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
- constexpr bool A::is_reference_v<T> = true;
-
- template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
- constexpr bool A::is_reference_v<T> = false;
-}
-#endif
+#include "partial-2.h"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_b.C b/gcc/testsuite/g++.dg/modules/partial-2_b.C
index 0af41ef..1b0c7a5 100644
--- a/gcc/testsuite/g++.dg/modules/partial-2_b.C
+++ b/gcc/testsuite/g++.dg/modules/partial-2_b.C
@@ -2,20 +2,4 @@
// { dg-additional-options -fmodules-ts }
module pr106826;
-static_assert(is_reference_v<int&>);
-static_assert(is_reference_v<int&&>);
-static_assert(!is_reference_v<int>);
-
-static_assert(A::is_reference_v<long&>);
-static_assert(A::is_reference_v<long&&>);
-static_assert(!A::is_reference_v<long>);
-
-#if __cpp_concepts
-static_assert(concepts::is_reference_v<char&>);
-static_assert(concepts::is_reference_v<char&&>);
-static_assert(!concepts::is_reference_v<char>);
-
-static_assert(concepts::A::is_reference_v<bool&>);
-static_assert(concepts::A::is_reference_v<bool&&>);
-static_assert(!concepts::A::is_reference_v<bool>);
-#endif
+#include "partial-2.cc"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_c.H b/gcc/testsuite/g++.dg/modules/partial-2_c.H
new file mode 100644
index 0000000..bd83852
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_c.H
@@ -0,0 +1,5 @@
+// PR c++/107033
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+#include "partial-2.h"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_d.C b/gcc/testsuite/g++.dg/modules/partial-2_d.C
new file mode 100644
index 0000000..ed54d3c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_d.C
@@ -0,0 +1,8 @@
+// PR c++/107033
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr107033 }
+export module pr107033;
+
+import "partial-2_c.H";
+
+#include "partial-2.cc"
diff --git a/gcc/testsuite/g++.dg/other/mult-stor1.C b/gcc/testsuite/g++.dg/other/mult-stor1.C
index 1eaec4f1..e582b03 100644
--- a/gcc/testsuite/g++.dg/other/mult-stor1.C
+++ b/gcc/testsuite/g++.dg/other/mult-stor1.C
@@ -4,5 +4,5 @@
struct A
{
- extern static int i; // { dg-error "conflicting specifiers" }
+ extern static int i; // { dg-error "'static' specifier conflicts with 'extern'" }
};
diff --git a/gcc/testsuite/g++.dg/parse/crash39.C b/gcc/testsuite/g++.dg/parse/crash39.C
index 2f39c10..5d4e02d 100644
--- a/gcc/testsuite/g++.dg/parse/crash39.C
+++ b/gcc/testsuite/g++.dg/parse/crash39.C
@@ -1,3 +1,3 @@
// PR c++/31747
-static extern int i; // { dg-error "conflicting specifiers" }
+static extern int i; // { dg-error "'extern' specifier conflicts with 'static'" }
diff --git a/gcc/testsuite/g++.dg/parse/typedef8.C b/gcc/testsuite/g++.dg/parse/typedef8.C
index 60b8f39..e21bdb9 100644
--- a/gcc/testsuite/g++.dg/parse/typedef8.C
+++ b/gcc/testsuite/g++.dg/parse/typedef8.C
@@ -1,11 +1,11 @@
//PR c++ 29024
-typedef static int a; // { dg-error "conflicting" }
-typedef register int b; // { dg-error "conflicting" }
-typedef extern int c; // { dg-error "conflicting" }
-static typedef int a; // { dg-error "conflicting" }
+typedef static int a; // { dg-error "'static' specifier conflicts with 'typedef'" }
+typedef register int b; // { dg-error "'register' specifier conflicts with 'typedef'" }
+typedef extern int c; // { dg-error "'extern' specifier conflicts with 'typedef'" }
+static typedef int a; // { dg-error "'typedef' specifier conflicts with 'static'" }
void foo()
{
- typedef auto int bar; // { dg-error "conflicting|two or more data types" }
+ typedef auto int bar; // { dg-error "'auto' specifier conflicts with 'typedef'|two or more data types" }
}
diff --git a/gcc/testsuite/g++.dg/template/error30.C b/gcc/testsuite/g++.dg/template/error30.C
index 3a87872..5a3047c 100644
--- a/gcc/testsuite/g++.dg/template/error30.C
+++ b/gcc/testsuite/g++.dg/template/error30.C
@@ -2,4 +2,4 @@
template<int> struct A;
-template<template<typename> class B> A<B<int>::x> operator() (); // { dg-error "51:.A<B<int>::x> operator\\(\\)\\(\\). must be a non-static member function" }
+template<template<typename> class B> A<B<int>::x> operator() (); // { dg-error "51:.A<B<int>::x> operator\\(\\)\\(\\). must be a member function" }
diff --git a/gcc/testsuite/g++.dg/torture/pr107029.C b/gcc/testsuite/g++.dg/torture/pr107029.C
new file mode 100644
index 0000000..93c7f28
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr107029.C
@@ -0,0 +1,19 @@
+// PR tree-optimization/107029
+// { dg-do compile }
+
+struct S { long long a; int b; };
+long long S::*a;
+int S::*b;
+struct A { void foo (bool, bool); void bar (); int c; };
+
+void
+A::foo (bool a, bool b)
+{
+ c = a || b;
+}
+
+void
+A::bar()
+{
+ foo (a, b);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/operator.C b/gcc/testsuite/g++.old-deja/g++.jason/operator.C
index 79c1932..c187901 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/operator.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/operator.C
@@ -6,7 +6,7 @@ typedef __SIZE_TYPE__ size_t;
struct A {
int operator?:(int a, int b); // { dg-error "prohibits overloading" }
- static int operator()(int a); // { dg-error "14:.static int A::operator\\(\\)\\(int\\). must be a non-static member function" }
+ static int operator()(int a); // { dg-warning "14:.static int A::operator\\(\\)\\(int\\). may be a static member function only with" "" { target c++20_down } }
static int operator+(A,A); // { dg-error "14:.static int A::operator\\+\\(A, A\\). must be either a non-static member function or a non-member function" }
int operator+(int a, int b = 1); // { dg-error "7:.int A::operator\\+\\(int, int\\). must have either zero or one argument" }
int operator++(char); // { dg-error "7:postfix .int A::operator\\+\\+\\(char\\). must have .int. as its argument" }
diff --git a/gcc/testsuite/g++.target/i386/float16-1.C b/gcc/testsuite/g++.target/i386/float16-1.C
index 95d1ac2..f96b932 100644
--- a/gcc/testsuite/g++.target/i386/float16-1.C
+++ b/gcc/testsuite/g++.target/i386/float16-1.C
@@ -1,8 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mno-sse2" } */
-_Float16/* { dg-error "does not name a type" } */
+_Float16 /* { dg-error "expected unqualified-id before '_Float16'" } */
foo (_Float16 x)
{
return x;
-}
+} /* { dg-error "'_Float16' is not supported on this target" } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount6.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount6.c
new file mode 100644
index 0000000..1406ad9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount6.c
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp" }
+
+int g(int n)
+{
+ n &= 0x8000;
+ if (n == 0)
+ return 1;
+ return __builtin_popcount(n);
+}
+
+// { dg-final { scan-tree-dump "return 1;" "evrp" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c
new file mode 100644
index 0000000..5010aed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-dom2-alias" }
+
+typedef __SIZE_TYPE__ size_t;
+
+void saxpy(size_t n)
+{
+ if (n == 0 || n % 8 != 0)
+ __builtin_unreachable();
+
+ extern void foobar (size_t n);
+ foobar (n);
+}
+
+// { dg-final { scan-tree-dump "NONZERO.*fff8" "dom2" } }
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
index f909099..67635fb 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -mtune=generic -fno-common" } */
+/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -mtune=generic -fno-common -mno-avx512f" } */
#define N 1024
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-1.c b/gcc/testsuite/gcc.target/i386/pr53346-1.c
new file mode 100644
index 0000000..6d230da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-1.c
@@ -0,0 +1,70 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -O2 -mno-sse3" } */
+/* { dg-final { scan-assembler-times "shufps" 15 } } */
+/* { dg-final { scan-assembler-times "pshufd" 2 } } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+v4si
+__attribute__((noipa))
+foo (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 5, 3);
+}
+
+v4si
+__attribute__((noipa))
+foo1 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 5, 2, 3);
+}
+
+v4si
+__attribute__((noipa))
+foo2 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 3, 5);
+}
+
+v4si
+__attribute__((noipa))
+foo3 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 4, 5, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo4 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 3, 6, 7, 5);
+}
+
+v4si
+__attribute__((noipa))
+foo5 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 7, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo6 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 3, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo7 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 3, 4, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo8 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 6, 3);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-2.c b/gcc/testsuite/gcc.target/i386/pr53346-2.c
new file mode 100644
index 0000000..0c6c7b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-2.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-require-effective-target sse2 } */
+
+#include "sse2-check.h"
+#include "pr53346-1.c"
+
+static void
+sse2_test ()
+{
+ v4si a = __extension__(v4si) { 0, 1, 2, 3 };
+ v4si b = __extension__(v4si) { 4, 5, 6, 7 };
+ v4si exp = __extension__(v4si) { 1, 2, 5, 3 };
+ v4si dest;
+ dest = foo (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 1, 5, 2, 3 };
+ dest = foo1 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 1, 2, 3, 5 };
+ dest = foo2 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 1, 4, 5, 6 };
+ dest = foo3 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 3, 6, 7, 5 };
+ dest = foo4 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 4, 7, 6 };
+ dest = foo5 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 4, 3, 6 };
+ dest = foo6 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 3, 4, 6 };
+ dest = foo7 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 4, 6, 3 };
+ dest = foo8 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-3.c b/gcc/testsuite/gcc.target/i386/pr53346-3.c
new file mode 100644
index 0000000..0b204f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-3.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -O2 -mno-sse3" } */
+/* { dg-final { scan-assembler-times "shufps" 17 } } */
+
+typedef float v4sf __attribute__((vector_size(16)));
+
+v4sf
+__attribute__((noipa))
+foo (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 5, 3);
+}
+
+v4sf
+__attribute__((noipa))
+foo1 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 5, 2, 3);
+}
+
+v4sf
+__attribute__((noipa))
+foo2 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 3, 5);
+}
+
+v4sf
+__attribute__((noipa))
+foo3 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 4, 5, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo4 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 3, 6, 7, 5);
+}
+
+v4sf
+__attribute__((noipa))
+foo5 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 7, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo6 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 3, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo7 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 3, 4, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo8 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 6, 3);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-4.c b/gcc/testsuite/gcc.target/i386/pr53346-4.c
new file mode 100644
index 0000000..9e4e45b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-4.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-require-effective-target sse2 } */
+
+#include "sse2-check.h"
+#include "pr53346-3.c"
+
+static void
+sse2_test ()
+{
+ v4sf a = __extension__(v4sf) { 0, 1, 2, 3 };
+ v4sf b = __extension__(v4sf) { 4, 5, 6, 7 };
+ v4sf exp = __extension__(v4sf) { 1, 2, 5, 3 };
+ v4sf dest;
+ dest = foo (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 1, 5, 2, 3 };
+ dest = foo1 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 1, 2, 3, 5 };
+ dest = foo2 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 1, 4, 5, 6 };
+ dest = foo3 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 3, 6, 7, 5 };
+ dest = foo4 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 4, 7, 6 };
+ dest = foo5 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 4, 3, 6 };
+ dest = foo6 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 3, 4, 6 };
+ dest = foo7 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 4, 6, 3 };
+ dest = foo8 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100645.c b/gcc/testsuite/gcc.target/powerpc/pr100645.c
new file mode 100644
index 0000000..c4e92cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100645.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-mdejagnu-cpu=power6 -maltivec" } */
+
+/* This used to ICE. */
+
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+v2di
+foo_v2di_l (v2di x)
+{
+ return __builtin_shuffle ((v2di){0, 0}, x, (v2di){3, 0});
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96072.c b/gcc/testsuite/gcc.target/powerpc/pr96072.c
new file mode 100644
index 0000000..10341c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr96072.c
@@ -0,0 +1,14 @@
+/* { dg-options "-O2" } */
+
+/* This used to ICE with the SYSV ABI (PR96072). */
+
+void
+he (int jn)
+{
+ {
+ int bh[jn];
+ if (jn != 0)
+ goto wa;
+ }
+wa:;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/ret-1.c b/gcc/testsuite/gcc.target/riscv/ret-1.c
new file mode 100644
index 0000000..28133aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ret-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -dp" } */
+/* This was extracted from coremark. */
+
+
+typedef signed short ee_s16;
+typedef struct list_data_s
+{
+ ee_s16 data16;
+ ee_s16 idx;
+} list_data;
+
+typedef struct list_head_s
+{
+ struct list_head_s *next;
+ struct list_data_s *info;
+} list_head;
+
+
+list_head *
+core_list_find(list_head *list, list_data *info)
+{
+ if (info->idx >= 0)
+ {
+ while (list && (list->info->idx != info->idx))
+ list = list->next;
+ return list;
+ }
+ else
+ {
+ while (list && ((list->info->data16 & 0xff) != info->data16))
+ list = list->next;
+ return list;
+ }
+}
+
+/* There is only one legitimate unconditional jump, so test for that,
+ which will catch the case where bb-reorder leaves a jump to a ret
+ in the IL. */
+/* { dg-final { scan-assembler-times "jump" 1 } } */
+
diff --git a/gcc/testsuite/gdc.test/compilable/commontype.d b/gcc/testsuite/gdc.test/compilable/commontype.d
index 076e29b..abe956c 100644
--- a/gcc/testsuite/gdc.test/compilable/commontype.d
+++ b/gcc/testsuite/gdc.test/compilable/commontype.d
@@ -151,19 +151,19 @@ static assert(Error!( uint*, int* ));
static assert(is( X!( int function(), int function() ) == int function() ));
// void pointer
-static assert(is( X!( void*, int* ) == int* ));
-static assert(is( X!( int*, void* ) == int* ));
-static assert(is( X!( const(int)*, void* ) == const(int)* ));
-static assert(is( X!( const(int*), void* ) == const(int*) ));
-static assert(is( X!( int*, const(void)* ) == int* )); // `const`
-static assert(is( X!( int*, const(void*) ) == int* )); // `const`
-static assert(is( X!( int*, shared(void*) ) == int* )); // should fail
-static assert(is( X!( int*, shared(void)* ) == int* )); // should fail
+static assert(is( X!( void*, int* ) == void* ));
+static assert(is( X!( int*, void* ) == void* ));
+static assert(is( X!( const(int)*, void* ) == void* ));
+static assert(is( X!( const(int*), void* ) == void* ));
+static assert(is( X!( int*, const(void)* ) == const(void)* )); // `const`
+static assert(is( X!( int*, const(void*) ) == const(void*) )); // `const`
+static assert(is( X!( int*, shared(void*) ) == shared(void*) )); // should fail
+static assert(is( X!( int*, shared(void)* ) == shared(void)* )); // should fail
static assert(Error!( int**, void** )); // should work
-static assert(is( X!( void*, int function() ) == int function() ));
-static assert(is( X!( immutable(void*), int function() ) == int function() )); // `const`
+static assert(is( X!( void*, int function() ) == void* ));
+static assert(is( X!( immutable(void*), int function() ) == immutable(void*) )); // `const`
// implicit conversion
static assert(is( X!( int*, const(int*) ) == const(int*) ));
diff --git a/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i b/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i
new file mode 100644
index 0000000..c8ff976
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i
@@ -0,0 +1,4 @@
+extern int xx;
+
+typedef struct Foo *FooRef;
+FooRef make_foo(void);
diff --git a/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i b/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i
new file mode 100644
index 0000000..03b22b2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i
@@ -0,0 +1,4 @@
+extern int xx;
+
+typedef struct Foo *FooRef;
+void free_foo(FooRef foo);
diff --git a/gcc/testsuite/gdc.test/compilable/imports/format23327.d b/gcc/testsuite/gdc.test/compilable/imports/format23327.d
new file mode 100644
index 0000000..de9b957
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/format23327.d
@@ -0,0 +1,7 @@
+module imports.format23327;
+
+import imports.format23327.write;
+
+immutable(string) format23327() { }
+
+import imports.format23327.internal.write;
diff --git a/gcc/testsuite/gdc.test/compilable/imports/format23327/write.d b/gcc/testsuite/gdc.test/compilable/imports/format23327/write.d
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/format23327/write.d
diff --git a/gcc/testsuite/gdc.test/compilable/segfaultgolf.d b/gcc/testsuite/gdc.test/compilable/segfaultgolf.d
new file mode 100644
index 0000000..2ea125f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/segfaultgolf.d
@@ -0,0 +1,50 @@
+// https://issues.dlang.org/show_bug.cgi?id=23351
+enum strings =
+[
+"a[(b).",
+"[(a)(b).",
+"a(={@.()(",
+"a[b,[(c).",
+"a[b#([(c).",
+"[a@b[(c).",
+"[((a).",
+"[a)b[(c).",
+"a[b)[(c).",
+"a(b[(c).",
+"a[b()c[(d).",
+"a[(b[(c).",
+"a(b[(c).",
+"[(@@a b[(c).",
+"a[(!b)c[(d).",
+"[(^a)b[(c).",
+"a(b[(c).",
+"~[a.b[(c).",
+"[a).[(b c d(e[(f).",
+"[((a).",
+"[a}b[(c).",
+"a[b[c..(d).",
+"[1a.[(b).",
+"a[({in){,",
+"a[^in(b[c=])S....,",
+"a[({in[({)){,"
+];
+template KidNamedFinger(T)
+{
+
+}
+void dummy()
+{
+ static foreach(str; strings)
+ {
+ /*
+ The above strings are all gibberish, they should
+ fail to parse but not segfault the compiler.
+ */
+ {
+ enum exp = __traits(compiles, mixin(str));
+ static assert(!exp);
+ enum t = __traits(compiles, KidNamedFinger!(mixin(str)));
+ static assert(!t);
+ }
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/statictemplatethis.d b/gcc/testsuite/gdc.test/compilable/statictemplatethis.d
new file mode 100644
index 0000000..0236f2d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/statictemplatethis.d
@@ -0,0 +1,45 @@
+mixin template Constructors(){
+ this(){ }
+ this()immutable{ }
+ this()shared{ }
+}
+
+class A {
+public:
+ static T getInstance(this T)() {
+ return new T();
+ }
+private:
+ mixin Constructors;
+}
+
+class B : A {
+private:
+ mixin Constructors;
+}
+
+void f(){
+ auto a = (new A).getInstance;
+ auto b = (new B).getInstance;
+ static assert(is(typeof(a) == A));
+ static assert(is(typeof(b) == B));
+
+ auto ca = (new immutable A).getInstance;
+ auto sb = (new shared B).getInstance;
+ static assert(is(typeof(ca) == immutable A));
+ static assert(is(typeof(sb) == shared B));
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=10488
+version(none)
+void g(){
+ auto a = A.getInstance();
+ auto b = B.getInstance();
+ static assert(is(typeof(a)==A));
+ static assert(is(typeof(b)==B));
+
+ auto ai = (immutable(A)).getInstance();
+ auto bs = (shared(B)).getInstance();
+ static assert(is(typeof(ai)==immutable(A)));
+ static assert(is(typeof(bs)==shared(B)));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test13123.d b/gcc/testsuite/gdc.test/compilable/test13123.d
new file mode 100644
index 0000000..881eb1b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test13123.d
@@ -0,0 +1,38 @@
+auto inferNothrow()
+in
+{
+}
+out
+{
+}
+do
+{
+ return 1;
+}
+
+auto dontInferNothrowIn()
+in
+{
+ throw new Exception(null);
+}
+do
+{
+ return 1;
+}
+
+auto dontInferNothrowOut()
+out
+{
+ throw new Exception(null);
+}
+do
+{
+ return 1;
+}
+
+enum isNothrow(Attr...) = (Attr.length >= 1)
+ && (Attr[0] == "nothrow" || isNothrow!(Attr[1 .. $]));
+
+static assert(isNothrow!(__traits(getFunctionAttributes, inferNothrow)));
+static assert(!isNothrow!(__traits(getFunctionAttributes, dontInferNothrowIn)));
+static assert(!isNothrow!(__traits(getFunctionAttributes, dontInferNothrowOut)));
diff --git a/gcc/testsuite/gdc.test/compilable/test21243.d b/gcc/testsuite/gdc.test/compilable/test21243.d
new file mode 100644
index 0000000..20838dc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21243.d
@@ -0,0 +1,21 @@
+// Parsing - expressions
+auto a = auto ref (int x) => x;
+auto b = auto ref (int x) { return x; };
+auto c = function auto ref (int x) { return x; };
+auto d = delegate auto ref (int x) { return x; };
+
+// Parsing - aliases
+alias e = auto ref (int x) => x;
+alias f = auto ref (int x) { return x; };
+alias g = function auto ref (int x) { return x; };
+alias h = delegate auto ref (int x) { return x; };
+
+// Semantic
+void test()
+{
+ alias fun(alias x) = auto ref () => x;
+ int n = 123;
+ auto _ = fun!123();
+ static assert(!__traits(compiles, &fun!123())); // rvalue
+ fun!n() = 456; // lvalue
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test21956.d b/gcc/testsuite/gdc.test/compilable/test21956.d
new file mode 100644
index 0000000..64ebc55
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21956.d
@@ -0,0 +1,16 @@
+// https://issues.dlang.org/show_bug.cgi?id=21956
+
+noreturn[noreturn] nrnr;
+
+void gun()
+{
+ foreach (a; nrnr){}
+}
+
+int main()
+{
+ noreturn[] empty;
+ int val;
+ foreach(el; empty) val++;
+ return val;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22674.d b/gcc/testsuite/gdc.test/compilable/test22674.d
new file mode 100644
index 0000000..cc6e3bb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22674.d
@@ -0,0 +1,10 @@
+// https://issues.dlang.org/show_bug.cgi?id=22674
+// EXTRA_FILES: imports/cimports2a.i imports/cimports2b.i
+
+import imports.cimports2a;
+import imports.cimports2b;
+
+void do_foo(){
+ FooRef f = make_foo(); // use_foo.d(5)
+ free_foo(f); // use_foo.d(6)
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23173.d b/gcc/testsuite/gdc.test/compilable/test23173.d
new file mode 100644
index 0000000..6b16132
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23173.d
@@ -0,0 +1,6 @@
+// REQUIRED_ARGS: -o-
+// https://issues.dlang.org/show_bug.cgi?id=23173
+
+mixin("long l = ", long.min, ";");
+static assert(mixin(long.min) == long.min);
+static assert(is(typeof(mixin(long.min)) == long));
diff --git a/gcc/testsuite/gdc.test/compilable/test23258.d b/gcc/testsuite/gdc.test/compilable/test23258.d
new file mode 100644
index 0000000..1e8e91b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23258.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=23258
+
+struct SumType(Types...)
+{
+ this(Types[0])
+ {
+ }
+ this(Types[1])
+ {
+ }
+}
+
+alias A2 = SumType!(C1[], C2[]);
+
+class C1
+{
+}
+
+class C2
+{
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23306.d b/gcc/testsuite/gdc.test/compilable/test23306.d
new file mode 100644
index 0000000..81b51f6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23306.d
@@ -0,0 +1,7 @@
+class A {
+ @disable new();
+}
+
+void main() {
+ scope A a = new A();
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23327.d b/gcc/testsuite/gdc.test/compilable/test23327.d
new file mode 100644
index 0000000..bbb6346
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23327.d
@@ -0,0 +1,3 @@
+// https://issues.dlang.org/show_bug.cgi?id=23327
+// EXTRA_FILES: imports/format23327.d imports/format23327/write.d
+import imports.format23327;
diff --git a/gcc/testsuite/gdc.test/compilable/vararg.d b/gcc/testsuite/gdc.test/compilable/vararg.d
new file mode 100644
index 0000000..79826a0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/vararg.d
@@ -0,0 +1,20 @@
+void main ()
+{
+ variance([1.0, 2, 3]);
+}
+
+alias meanType(T) = T;
+
+template variance(bool stable = true)
+{
+ void variance(Range)(Range r, bool isPopulation = false)
+ {
+ .variance!(double, stable)(r, isPopulation);
+ }
+}
+
+template variance(F, bool stable = true)
+{
+ void variance(Range)(Range r, bool isPopulation = false) {}
+ void variance(scope const F[] ar...) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10169.d b/gcc/testsuite/gdc.test/fail_compilation/diag10169.d
index 72becf2..84d0ad4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10169.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10169.d
@@ -2,7 +2,7 @@
EXTRA_FILES: imports/a10169.d
TEST_OUTPUT:
---
-fail_compilation/diag10169.d(12): Error: no property `x` for type `imports.a10169.B`
+fail_compilation/diag10169.d(12): Error: no property `x` for `B(0)` of type `imports.a10169.B`
---
*/
import imports.a10169;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10783.d b/gcc/testsuite/gdc.test/fail_compilation/diag10783.d
index f18341f..80c7f5e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10783.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10783.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag10783.d(14): Error: no property `type` for type `diag10783.Event`
+fail_compilation/diag10783.d(14): Error: no property `type` for `event` of type `diag10783.Event`
fail_compilation/diag10783.d(14): Error: undefined identifier `En`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13528.d b/gcc/testsuite/gdc.test/fail_compilation/diag13528.d
index 5d908f7..9b5761f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag13528.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag13528.d
@@ -1,10 +1,12 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag13528.d(13): Error: value of `this` is not known at compile time
-fail_compilation/diag13528.d(13): while evaluating `pragma(msg, __traits(getMember, A, "foo"))`
+fail_compilation/diag13528.d(6): Error: value of `this` is not known at compile time
+fail_compilation/diag13528.d(6): while evaluating `pragma(msg, __traits(getMember, A, "foo"))`
+fail_compilation/diag13528.d(12): parent scope from here: `mixin MyTemplate!()`
---
*/
+#line 1
mixin template MyTemplate()
{
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14145.d b/gcc/testsuite/gdc.test/fail_compilation/diag14145.d
index 6447f5e..fa7c611 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag14145.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14145.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag14145.d(15): Error: no property `i` for type `diag14145.main.Capture!(i)`
+fail_compilation/diag14145.d(15): Error: no property `i` for `_` of type `diag14145.main.Capture!(i)`
fail_compilation/diag14145.d(15): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
fail_compilation/diag14145.d(34): Error: expression `*this.ptr` of type `shared(int)` is not implicitly convertible to return type `ref int`
fail_compilation/diag14145.d(16): Error: template instance `diag14145.main.Capture!(i).Capture.opDispatch!"i"` error instantiating
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag15713.d b/gcc/testsuite/gdc.test/fail_compilation/diag15713.d
index 1c61408..e4cb2a7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag15713.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag15713.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag15713.d(19): Error: no property `widthSign` for type `diag15713.WrData.Data`
+fail_compilation/diag15713.d(19): Error: no property `widthSign` for `this` of type `diag15713.WrData.Data`
fail_compilation/diag15713.d(39): Error: template instance `diag15713.conwritefImpl!("parse-int", "width", "\n", Data(null))` error instantiating
fail_compilation/diag15713.d(44): instantiated from here: `conwritefImpl!("main", "\n", Data(null))`
fail_compilation/diag15713.d(49): instantiated from here: `fdwritef!()`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag23355.d b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d
new file mode 100644
index 0000000..586cbb0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag23355.d
@@ -0,0 +1,16 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/diag23355.d(1): Error: undefined identifier `n`
+fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi1` are callable using argument types `!()(int[4])`
+fail_compilation/diag23355.d(1): Candidate is: `ffi1(T)(T[n] s)`
+fail_compilation/diag23355.d(2): Error: undefined identifier `n`
+fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi2` are callable using argument types `!()(int[4])`
+fail_compilation/diag23355.d(2): Candidate is: `ffi2()(T[n] s)`
+---
+*/
+#line 1
+void ffi1(T)(T[n] s) { }
+void ffi2()(T[n] s) { }
+
+void main() { int[4] x; ffi1(x); ffi2(x); }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag3438.d b/gcc/testsuite/gdc.test/fail_compilation/diag3438.d
index 445f6d5..c4cbc72 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag3438.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag3438.d
@@ -1,4 +1,3 @@
-// REQUIRED_ARGS: -de
/*
TEST_OUTPUT:
---
@@ -8,6 +7,7 @@ fail_compilation/diag3438.d(20): Error: constructor `diag3438.F5.this` is marked
fail_compilation/diag3438.d(20): Use `@disable this();` if you want to disable default initialization.
fail_compilation/diag3438.d(21): Error: constructor `diag3438.F6.this` is marked `@disable`, so it cannot have default arguments for all parameters.
fail_compilation/diag3438.d(21): Use `@disable this();` if you want to disable default initialization.
+fail_compilation/diag3438.d(24): Error: default argument expected for `y`
---
*/
@@ -19,3 +19,6 @@ struct F3 { this(...) { } } // ok
struct F4 { this(int[] x...) { } } // ok
struct F5 { @disable this(int x = 1); }
struct F6 { @disable this(int x = 1) { } }
+
+// Make sure the deprecation doesn't interfere w/ the check for default arguments
+struct S { this(int x = 1, int y) { } }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag3438b.d b/gcc/testsuite/gdc.test/fail_compilation/diag3438b.d
deleted file mode 100644
index 46a197d..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/diag3438b.d
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/diag3438b.d(9): Error: default argument expected for `y`
----
-*/
-
-// Make sure the deprecation doesn't interfere w/ the check for default arguments
-struct S { this(int x = 1, int y) { } }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8894.d b/gcc/testsuite/gdc.test/fail_compilation/diag8894.d
index 9e0dadd..7cf3023 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8894.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8894.d
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag8894.d(16): Error: no property `x` for type `diag8894.Foo`
-fail_compilation/diag8894.d(17): Error: no property `y` for type `diag8894.Foo`
-fail_compilation/diag8894.d(18): Error: no property `x` for type `diag8894.Foo`
-fail_compilation/diag8894.d(19): Error: no property `x` for type `diag8894.Foo`
+fail_compilation/diag8894.d(16): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(17): Error: no property `y` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(18): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(19): Error: no property `x` for `f` of type `diag8894.Foo`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip22a.d b/gcc/testsuite/gdc.test/fail_compilation/dip22a.d
index bf04a51..324d217 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/dip22a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/dip22a.d
@@ -2,11 +2,11 @@
EXTRA_FILES: imports/dip22a.d
TEST_OUTPUT:
---
-fail_compilation/dip22a.d(16): Error: no property `bar` for type `imports.dip22a.Klass`
-fail_compilation/dip22a.d(17): Error: no property `bar` for type `imports.dip22a.Struct`
+fail_compilation/dip22a.d(16): Error: no property `bar` for `new Klass` of type `imports.dip22a.Klass`
+fail_compilation/dip22a.d(17): Error: no property `bar` for `Struct()` of type `imports.dip22a.Struct`
fail_compilation/dip22a.d(18): Error: undefined identifier `bar` in module `imports.dip22a`
-fail_compilation/dip22a.d(19): Error: no property `bar` for type `void`
-fail_compilation/dip22a.d(20): Error: no property `bar` for type `int`
+fail_compilation/dip22a.d(19): Error: no property `bar` for `Template!int` of type `void`
+fail_compilation/dip22a.d(20): Error: no property `bar` for `12` of type `int`
---
*/
import imports.dip22a;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d
index 33bee25..92e0734 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_1.d
@@ -1,14 +1,15 @@
/*
TEST_OUTPUT:
---
-fail_compilation/e15876_1.d(15): Error: valid scope identifiers are `exit`, `failure`, or `success`, not `x`
-fail_compilation/e15876_1.d(16): Error: found `End of File` when expecting `)`
-fail_compilation/e15876_1.d(16): Error: found `End of File` instead of statement
-fail_compilation/e15876_1.d(16): Error: found `End of File` when expecting `}` following compound statement
-fail_compilation/e15876_1.d(16): Error: found `End of File` when expecting `]`
-fail_compilation/e15876_1.d(16): Error: no identifier for declarator `o[()
+fail_compilation/e15876_1.d(16): Error: valid scope identifiers are `exit`, `failure`, or `success`, not `x`
+fail_compilation/e15876_1.d(17): Error: found `End of File` when expecting `)`
+fail_compilation/e15876_1.d(17): Error: found `End of File` instead of statement
+fail_compilation/e15876_1.d(17): Error: found `End of File` when expecting `}` following compound statement
+fail_compilation/e15876_1.d(17): Error: found `End of File` when expecting `]`
+fail_compilation/e15876_1.d(17): Error: no identifier for declarator `o[()
{
-scope(exit) }
+scope(exit) __error__
+}
]`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d
index ae5f77a..fe7d546 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_3.d
@@ -1,25 +1,27 @@
/*
TEST_OUTPUT:
---
-fail_compilation/e15876_3.d(25): Error: unexpected `(` in declarator
-fail_compilation/e15876_3.d(25): Error: basic type expected, not `=`
-fail_compilation/e15876_3.d(26): Error: found `End of File` when expecting `(`
-fail_compilation/e15876_3.d(26): Error: found `End of File` instead of statement
-fail_compilation/e15876_3.d(26): Error: expression expected, not `End of File`
-fail_compilation/e15876_3.d(26): Error: found `End of File` when expecting `;` following `for` condition
-fail_compilation/e15876_3.d(26): Error: expression expected, not `End of File`
-fail_compilation/e15876_3.d(26): Error: found `End of File` when expecting `)`
-fail_compilation/e15876_3.d(26): Error: found `End of File` instead of statement
-fail_compilation/e15876_3.d(26): Error: found `End of File` when expecting `}` following compound statement
-fail_compilation/e15876_3.d(26): Error: found `End of File` when expecting `)`
-fail_compilation/e15876_3.d(26): Error: no identifier for declarator `d(_error_ = ()
+fail_compilation/e15876_3.d(27): Error: unexpected `(` in declarator
+fail_compilation/e15876_3.d(27): Error: basic type expected, not `=`
+fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `(`
+fail_compilation/e15876_3.d(28): Error: found `End of File` instead of statement
+fail_compilation/e15876_3.d(28): Error: expression expected, not `End of File`
+fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `;` following `for` condition
+fail_compilation/e15876_3.d(28): Error: expression expected, not `End of File`
+fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `)`
+fail_compilation/e15876_3.d(28): Error: found `End of File` instead of statement
+fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `}` following compound statement
+fail_compilation/e15876_3.d(28): Error: found `End of File` when expecting `)`
+fail_compilation/e15876_3.d(28): Error: no identifier for declarator `d(_error_ = ()
{
-for (; 0; 0)
+for (__error__
+ 0; 0)
{
+__error__
}
}
)`
-fail_compilation/e15876_3.d(26): Error: semicolon expected following function declaration
+fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration
---
*/
d(={for
diff --git a/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d b/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d
index 6f46633..f4bd407 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/e15876_4.d
@@ -1,20 +1,22 @@
/*
TEST_OUTPUT:
---
-fail_compilation/e15876_4.d(23): Error: found `)` when expecting `(`
-fail_compilation/e15876_4.d(24): Error: found `End of File` when expecting `(`
-fail_compilation/e15876_4.d(24): Error: found `End of File` instead of statement
-fail_compilation/e15876_4.d(24): Error: expression expected, not `End of File`
-fail_compilation/e15876_4.d(24): Error: found `End of File` when expecting `;` following `for` condition
-fail_compilation/e15876_4.d(24): Error: expression expected, not `End of File`
-fail_compilation/e15876_4.d(24): Error: found `End of File` when expecting `)`
-fail_compilation/e15876_4.d(24): Error: found `End of File` instead of statement
-fail_compilation/e15876_4.d(24): Error: found `End of File` when expecting `}` following compound statement
-fail_compilation/e15876_4.d(24): Error: found `End of File` when expecting `)`
-fail_compilation/e15876_4.d(24): Error: no identifier for declarator `typeof(()
+fail_compilation/e15876_4.d(25): Error: found `)` when expecting `(`
+fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `(`
+fail_compilation/e15876_4.d(26): Error: found `End of File` instead of statement
+fail_compilation/e15876_4.d(26): Error: expression expected, not `End of File`
+fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `;` following `for` condition
+fail_compilation/e15876_4.d(26): Error: expression expected, not `End of File`
+fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `)`
+fail_compilation/e15876_4.d(26): Error: found `End of File` instead of statement
+fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `}` following compound statement
+fail_compilation/e15876_4.d(26): Error: found `End of File` when expecting `)`
+fail_compilation/e15876_4.d(26): Error: no identifier for declarator `typeof(()
{
-for (; 0; 0)
+for (__error__
+ 0; 0)
{
+__error__
}
}
)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d
index e969b24..cfda8f4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10968.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10968.d
@@ -1,27 +1,28 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail10968.d(42): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(42): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(30): `fail10968.SA.__postblit` is declared here
fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(30): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(30): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arrayassign_l!(SA[], SA)._d_arrayassign_l`
-fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(47): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(30): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arraysetassign!(SA[], SA)._d_arraysetassign`
+fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.arrayassign._d_arrayassign_l!(SA[], SA)._d_arrayassign_l`
fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(30): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor`
+fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
fail_compilation/fail10968.d(49): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(30): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor`
+fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(49): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor`
+fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(50): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(31): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(50): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor`
---
*/
@@ -52,12 +53,12 @@ void bar() pure @safe
/*
TEST_OUTPUT:
---
-fail_compilation/fail10968.d(75): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
fail_compilation/fail10968.d(76): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
fail_compilation/fail10968.d(77): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(80): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(78): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
fail_compilation/fail10968.d(81): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
fail_compilation/fail10968.d(82): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(83): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail121.d b/gcc/testsuite/gdc.test/fail_compilation/fail121.d
index 70e9d0c..8d5af74 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail121.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail121.d
@@ -3,8 +3,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail121.d(23): Error: no property `typeinfo` for type `fail121.myobject`
-fail_compilation/fail121.d(23): Error: no property `typeinfo` for type `int`
+fail_compilation/fail121.d(23): Error: no property `typeinfo` for `list[1]` of type `fail121.myobject`
+fail_compilation/fail121.d(23): Error: no property `typeinfo` for `i` of type `int`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13123.d b/gcc/testsuite/gdc.test/fail_compilation/fail13123.d
new file mode 100644
index 0000000..7784cba
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail13123.d
@@ -0,0 +1,21 @@
+// REQUIRED_ARGS: -de
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail13123.d(10): Deprecation: `fail13123.test`: `in` contract may throw but function is marked as `nothrow`
+fail_compilation/fail13123.d(10): Deprecation: `fail13123.test`: `out` contract may throw but function is marked as `nothrow`
+---
+*/
+
+void test() nothrow
+in
+{
+ throw new Exception(null);
+}
+out
+{
+ throw new Exception(null);
+}
+do
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17646.d b/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
index 3571e38..39e7cb9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17646.d
@@ -4,9 +4,8 @@ EXTRA_FILES: imports/fail17646.d
TEST_OUTPUT:
---
fail_compilation/imports/fail17646.d(10): Error: found `}` instead of statement
-fail_compilation/imports/fail17646.d(7): Error: function `imports.fail17646.allTestData!"".allTestData` has no `return` statement, but is expected to return a value of type `const(TestData)[]`
-fail_compilation/fail17646.d(16): Error: template instance `imports.fail17646.allTestData!""` error instantiating
-fail_compilation/fail17646.d(19): instantiated from here: `runTests!""`
+fail_compilation/fail17646.d(11): Error: function `fail17646.runTests!"".runTests` has no `return` statement, but is expected to return a value of type `int`
+fail_compilation/fail17646.d(18): Error: template instance `fail17646.runTests!""` error instantiating
---
*/
int runTests(Modules...)()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18892.d b/gcc/testsuite/gdc.test/fail_compilation/fail18892.d
index 531d1ed..0fb56d3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18892.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18892.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18892.d(20): Error: no property `foo` for type `fail18892.MT`
-fail_compilation/fail18892.d(21): Error: no property `foo` for type `fail18892.MT`
+fail_compilation/fail18892.d(20): Error: no property `foo` for `a` of type `fail18892.MT`
+fail_compilation/fail18892.d(21): Error: no property `foo` for `MT` of type `fail18892.MT`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18970.d b/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
index 0973217..a8156fe 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
@@ -1,9 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18970.d(24): Error: no property `y` for type `fail18970.S`
+fail_compilation/fail18970.d(24): Error: no property `y` for `S()` of type `fail18970.S`
fail_compilation/fail18970.d(24): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
-fail_compilation/fail18970.d(31): Error: no property `yyy` for type `fail18970.S2`
+fail_compilation/fail18970.d(31): Error: no property `yyy` for `this` of type `fail18970.S2`
fail_compilation/fail18970.d(31): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18979.d b/gcc/testsuite/gdc.test/fail_compilation/fail18979.d
index 9756570..04e36f6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18979.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18979.d
@@ -2,7 +2,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18979.d(13): Error: no property `__ctor` for type `imports.imp18979.Foo`
+fail_compilation/fail18979.d(13): Error: no property `__ctor` for `Foo()` of type `imports.imp18979.Foo`
----
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19103.d b/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
index 6b740ac..40fafcd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail19103.d(12): Error: no property `puts` for type `fail19103.C`
-fail_compilation/fail19103.d(14): Error: no property `puts` for type `fail19103.S1`
+fail_compilation/fail19103.d(12): Error: no property `puts` for `new C` of type `fail19103.C`
+fail_compilation/fail19103.d(14): Error: no property `puts` for `s1` of type `fail19103.S1`
fail_compilation/fail19103.d(16): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19687.d b/gcc/testsuite/gdc.test/fail_compilation/fail19687.d
index 7d1c6e5..0076091 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19687.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19687.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail19687.d(17): Error: no property `nonexisting` for type `string`
+fail_compilation/fail19687.d(17): Error: no property `nonexisting` for `""` of type `string`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19913.d b/gcc/testsuite/gdc.test/fail_compilation/fail19913.d
index fe2655e..c880923 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19913.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19913.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail19913.d(11): Error: no property `b` for type `int`
+fail_compilation/fail19913.d(11): Error: no property `b` for `a` of type `int`
fail_compilation/fail19913.d(11): Error: mixin `fail19913.S.b!()` is not defined
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21243.d b/gcc/testsuite/gdc.test/fail_compilation/fail21243.d
new file mode 100644
index 0000000..25df235
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21243.d
@@ -0,0 +1,19 @@
+/+ TEST_OUTPUT:
+---
+fail_compilation/fail21243.d(16): Error: found `(` when expecting `ref` and function literal following `auto`
+fail_compilation/fail21243.d(16): Error: semicolon expected following auto declaration, not `int`
+fail_compilation/fail21243.d(16): Error: semicolon needed to end declaration of `x` instead of `)`
+fail_compilation/fail21243.d(16): Error: declaration expected, not `)`
+fail_compilation/fail21243.d(17): Error: `auto` can only be used as part of `auto ref` for function literal return values
+fail_compilation/fail21243.d(18): Error: basic type expected, not `(`
+fail_compilation/fail21243.d(18): Error: function declaration without return type. (Note that constructors are always named `this`)
+fail_compilation/fail21243.d(18): Deprecation: storage class `auto` has no effect in type aliases
+fail_compilation/fail21243.d(18): Error: semicolon expected to close `alias` declaration
+fail_compilation/fail21243.d(18): Error: declaration expected, not `=>`
+fail_compilation/fail21243.d(19): Error: `auto` can only be used as part of `auto ref` for function literal return values
+---
++/
+auto a = auto (int x) => x;
+auto b = function auto (int x) { return x; };
+alias c = auto (int x) => x;
+alias d = function auto (int x) { return x; };
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23109.d b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
index 91b4e79..5c5c11b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
@@ -4,8 +4,8 @@ EXTRA_FILES: imports/test23109a.d imports/test23109b.d imports/test23109c.d
EXTRA_SOURCES: extra-files/test23109/object.d
TEST_OUTPUT:
---
-Error: no property `getHash` for type `object.TypeInfo_Const`
-Error: no property `getHash` for type `object.TypeInfo_Const`
+Error: no property `getHash` for `typeid(const(Ensure[]))` of type `object.TypeInfo_Const`
+Error: no property `getHash` for `typeid(const(Ensure[1]))` of type `object.TypeInfo_Const`
fail_compilation/imports/test23109a.d(10): Error: template instance `imports.test23109a.Array!(Ensure)` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7372.d b/gcc/testsuite/gdc.test/fail_compilation/fail7372.d
new file mode 100644
index 0000000..2d56e09
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7372.d
@@ -0,0 +1,13 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/fail7372.d(7): Error: undefined identifier `X`
+fail_compilation/fail7372.d(4): parent scope from here: `mixin Issue7372!()`
+---
+*/
+#line 1
+import imports.fail7372;
+interface I {}
+class C : I {
+ mixin Issue7372!();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d b/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d
index d7853e6..c44b289 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/faildottypeinfo.d(11): Error: no property `typeinfo` for type `int`
+fail_compilation/faildottypeinfo.d(11): Error: no property `typeinfo` for `0` of type `int`
fail_compilation/faildottypeinfo.d(12): Error: no property `typeinfo` for type `object.Object`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/failoffset.d b/gcc/testsuite/gdc.test/fail_compilation/failoffset.d
index bbec698..ff0d26b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/failoffset.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/failoffset.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/failoffset.d(12): Error: no property `offset` for type `int`
+fail_compilation/failoffset.d(12): Error: no property `offset` for `b` of type `int`
fail_compilation/failoffset.d(12): while evaluating: `static assert(b.offset == 4)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10938.d b/gcc/testsuite/gdc.test/fail_compilation/ice10938.d
index 2084e32..d21ee47 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10938.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10938.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice10938.d(13): Error: no property `opts` for type `ice10938.C`
+fail_compilation/ice10938.d(13): Error: no property `opts` for `this` of type `ice10938.C`
fail_compilation/ice10938.d(13): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice12174.d b/gcc/testsuite/gdc.test/fail_compilation/ice12174.d
index 019722a..dbe386e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice12174.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice12174.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice12174.d(12): Error: no property `sum` for type `int[]`
+fail_compilation/ice12174.d(12): Error: no property `sum` for `[1, 2, 3]` of type `int[]`
fail_compilation/ice12174.d(20): Error: CTFE failed because of previous errors in `this`
fail_compilation/ice12174.d(13): called from here: `filter([1, 2, 3])`
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice15855.d b/gcc/testsuite/gdc.test/fail_compilation/ice15855.d
index e800838..b26fe4c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice15855.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice15855.d
@@ -2,19 +2,21 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice15855.d(25): Error: found `End of File` when expecting `(`
-fail_compilation/ice15855.d(25): Error: found `End of File` instead of statement
-fail_compilation/ice15855.d(25): Error: expression expected, not `End of File`
-fail_compilation/ice15855.d(25): Error: found `End of File` when expecting `;` following `for` condition
-fail_compilation/ice15855.d(25): Error: expression expected, not `End of File`
-fail_compilation/ice15855.d(25): Error: found `End of File` when expecting `)`
-fail_compilation/ice15855.d(25): Error: found `End of File` instead of statement
-fail_compilation/ice15855.d(25): Error: found `End of File` when expecting `}` following compound statement
-fail_compilation/ice15855.d(25): Error: found `End of File` when expecting `]`
-fail_compilation/ice15855.d(25): Error: no identifier for declarator `a[()
+fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `(`
+fail_compilation/ice15855.d(27): Error: found `End of File` instead of statement
+fail_compilation/ice15855.d(27): Error: expression expected, not `End of File`
+fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `;` following `for` condition
+fail_compilation/ice15855.d(27): Error: expression expected, not `End of File`
+fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `)`
+fail_compilation/ice15855.d(27): Error: found `End of File` instead of statement
+fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `}` following compound statement
+fail_compilation/ice15855.d(27): Error: found `End of File` when expecting `]`
+fail_compilation/ice15855.d(27): Error: no identifier for declarator `a[()
{
-for (; 0; 0)
+for (__error__
+ 0; 0)
{
+__error__
}
}
]`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice18469.d b/gcc/testsuite/gdc.test/fail_compilation/ice18469.d
index 8803956..796dd3d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice18469.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice18469.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice18469.d(10): Error: no property `opCall` for type `void`
+fail_compilation/ice18469.d(10): Error: no property `opCall` for `this.~this()` of type `void`
---
*/
class Bar
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice19755.d b/gcc/testsuite/gdc.test/fail_compilation/ice19755.d
index f948477..6d60fc4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice19755.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice19755.d
@@ -1,6 +1,6 @@
/* TEST_OUTPUT:
---
-fail_compilation/ice19755.d(11): Error: no property `x` for type `ice19755.Thunk!int*`
+fail_compilation/ice19755.d(11): Error: no property `x` for `self` of type `ice19755.Thunk!int*`
fail_compilation/ice19755.d(16): Error: template instance `ice19755.Thunk!int` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail7372.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail7372.d
new file mode 100644
index 0000000..f71c736
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail7372.d
@@ -0,0 +1,9 @@
+module imports.fail7372;
+import imports.imp1;
+mixin template Issue7372()
+{
+ public void f()
+ {
+ int foo = X;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
index b50a616..11fddf0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
@@ -22,7 +22,6 @@ fail_compilation/misc_parser_err_cov1.d(39): Error: expression expected, not `;`
fail_compilation/misc_parser_err_cov1.d(40): Error: semicolon expected following auto declaration, not `auto`
fail_compilation/misc_parser_err_cov1.d(40): Error: identifier or `new` expected following `.`, not `+`
fail_compilation/misc_parser_err_cov1.d(41): Error: identifier or new keyword expected following `(...)`.
-fail_compilation/misc_parser_err_cov1.d(41): Error: found `.` when expecting `;` following statement
fail_compilation/misc_parser_err_cov1.d(41): Error: expression expected, not `;`
fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following statement
fail_compilation/misc_parser_err_cov1.d(43): Error: found `End of File` when expecting `}` following compound statement
diff --git a/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d b/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d
new file mode 100644
index 0000000..db8bf59
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/mixinprop.d
@@ -0,0 +1,13 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/mixinprop.d(12): Error: no property `x` for `mixin Foo!() F;
+` of type `void`
+---
+*/
+mixin template Foo() { }
+
+void main()
+{
+ mixin Foo F;
+ F.x;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15785.d b/gcc/testsuite/gdc.test/fail_compilation/test15785.d
index 23a3660..594b5d3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15785.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15785.d
@@ -2,7 +2,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test15785.d(16): Error: no property `foo` for type `imports.test15785.Base`
+fail_compilation/test15785.d(16): Error: no property `foo` for `super` of type `imports.test15785.Base`
fail_compilation/test15785.d(17): Error: undefined identifier `bar`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15897.d b/gcc/testsuite/gdc.test/fail_compilation/test15897.d
index e4ade7d..db554cb 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15897.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15897.d
@@ -3,7 +3,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test15897.d(19): Error: no property `create` for type `imports.test15897.Cat`
+fail_compilation/test15897.d(19): Error: no property `create` for `cat` of type `imports.test15897.Cat`
---
*/
module test15897;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16188.d b/gcc/testsuite/gdc.test/fail_compilation/test16188.d
index c4a0fa6..bdaae94 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16188.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16188.d
@@ -1,7 +1,7 @@
/* REQUIRED_ARGS: -preview=bitfields
* TEST_OUTPUT:
---
-fail_compilation/test16188.d(101): Error: no property `name` for type `test16188.Where`
+fail_compilation/test16188.d(101): Error: no property `name` for `Where()` of type `test16188.Where`
fail_compilation/test16188.d(101): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d b/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d
index 2456a59..f523337 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
(spec:1) fail_compilation/test17380spec.d(14): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
-(spec:1) fail_compilation/test17380spec.d(14): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for type `test17380spec.Uint128`
+(spec:1) fail_compilation/test17380spec.d(14): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for `this.opCast()` of type `test17380spec.Uint128`
fail_compilation/test17380spec.d(14): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21096.d b/gcc/testsuite/gdc.test/fail_compilation/test21096.d
index e32ad9c..302eb3d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21096.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21096.d
@@ -3,10 +3,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test21096.d(13): Error: identifier or new keyword expected following `(...)`.
-fail_compilation/test21096.d(13): Error: found `.` when expecting `]`
-fail_compilation/test21096.d(13): Error: no identifier for declarator `char`
-fail_compilation/test21096.d(13): Error: declaration expected, not `]`
+fail_compilation/test21096.d(11): Error: identifier or new keyword expected following `(...)`.
+fail_compilation/test21096.d(11): Error: no identifier for declarator `char[(__error)]`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22680.d b/gcc/testsuite/gdc.test/fail_compilation/test22680.d
new file mode 100644
index 0000000..caf0f4a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22680.d
@@ -0,0 +1,17 @@
+/* REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test22680.d(104): Error: scope variable `this` assigned to non-scope `c`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=22680
+
+#line 100
+
+C c;
+class C {
+ ~this() @safe {
+ c = this;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/newaa.d b/gcc/testsuite/gdc.test/runnable/newaa.d
new file mode 100644
index 0000000..94e79d5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/newaa.d
@@ -0,0 +1,23 @@
+void main()
+{
+ alias AA = int[string];
+ // aa is not ref
+ static void test(AA aa)
+ {
+ aa[""] = 0;
+ }
+ auto aa = new AA();
+ auto ab = new int[string];
+ auto ac = new typeof(aa);
+ test(aa);
+ test(ab);
+ test(ac);
+ assert(aa.length);
+ assert(ab.length);
+ assert(ac.length);
+
+ int[string] a = new int[string];
+ auto b = a;
+ a["seven"] = 7;
+ assert(b["seven"] == 7);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test23234.d b/gcc/testsuite/gdc.test/runnable/test23234.d
new file mode 100644
index 0000000..7872aa7
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test23234.d
@@ -0,0 +1,22 @@
+// https://issues.dlang.org/show_bug.cgi?id=23234
+
+class Bar
+{
+}
+
+class Foo
+{
+ Bar get() { return new Bar; }
+ alias get this;
+}
+
+void main()
+{
+ auto foo = new Foo;
+ void test(Bar delegate() dg)
+ {
+ assert(dg() !is null);
+ }
+
+ test(() => foo);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testassign.d b/gcc/testsuite/gdc.test/runnable/testassign.d
index f47d2b2..586aea8 100644
--- a/gcc/testsuite/gdc.test/runnable/testassign.d
+++ b/gcc/testsuite/gdc.test/runnable/testassign.d
@@ -230,6 +230,21 @@ void test5()
static assert(!__traits(compiles, s.err += 1));
}
+void test6()
+{
+ int dtors;
+ struct S6
+ {
+ @disable this(this);
+ ~this() { dtors++; }
+ }
+
+ S6[2] arr;
+ arr = S6();
+
+ assert(dtors == 2);
+}
+
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=4424
@@ -1192,6 +1207,7 @@ int main()
test3();
test4();
test5();
+ test6();
test4424();
test6174a();
test6174b();
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_10.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_10.f90
new file mode 100644
index 0000000..d8bc1bb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_10.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes in the case of non-polymorphic derived type arguments:
+! - one clobber to be emitted in the caller before calls to FOO in the *.original dump,
+! - no clobber to be emitted in the caller before calls to BAR in the *.original dump,
+! - the initialization constants to be optimized away in the *.optimized dump.
+
+module x
+ implicit none
+ type :: t
+ integer :: c
+ end type t
+ type, extends(t) :: u
+ integer :: d
+ end type u
+contains
+ subroutine foo(a)
+ type(t), intent(out) :: a
+ a = t(42)
+ end subroutine foo
+ subroutine bar(b)
+ class(t), intent(out) :: b
+ b%c = 24
+ end subroutine bar
+end module x
+
+program main
+ use x
+ implicit none
+ type(t) :: tc
+ type(u) :: uc, ud
+ class(t), allocatable :: te, tf
+
+ tc = t(123456789)
+ call foo(tc)
+ if (tc%c /= 42) stop 1
+
+ uc = u(987654321, 0)
+ call foo(uc%t)
+ if (uc%c /= 42) stop 2
+ if (uc%d /= 0) stop 3
+
+ ud = u(11223344, 0)
+ call bar(ud)
+ if (ud%c /= 24) stop 4
+
+ te = t(55667788)
+ call foo(te)
+ if (te%c /= 42) stop 5
+
+ tf = t(99887766)
+ call bar(tf)
+ if (tf%c /= 24) stop 6
+
+end program main
+
+! We don't support class descriptors, neither derived type components, so there is a clobber for tc only;
+! no clobber for uc, ud, te, tf.
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "tc = {CLOBBER};" "original" } }
+
+! There is a clobber for tc, so we should manage to optimize away the associated initialization constant (but not other
+! initialization constants).
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_4.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_4.f90
new file mode 100644
index 0000000..effbaa1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_4.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+!
+! PR fortran/106817
+! Check that for an actual argument whose dummy is INTENT(OUT),
+! the clobber that is emitted in the caller before a procedure call
+! happens after any expression depending on the argument value has been
+! evaluated.
+!
+
+module m
+ implicit none
+contains
+ subroutine copy1(out, in)
+ integer, intent(in) :: in
+ integer, intent(out) :: out
+ out = in
+ end subroutine copy1
+ subroutine copy2(in, out)
+ integer, intent(in) :: in
+ integer, intent(out) :: out
+ out = in
+ end subroutine copy2
+end module m
+
+program p
+ use m
+ implicit none
+ integer :: a, b
+
+ ! Clobbering of a should happen after a+1 has been evaluated.
+ a = 3
+ call copy1(a, a+1)
+ if (a /= 4) stop 1
+
+ ! Clobbering order does not depend on the order of arguments.
+ ! It should also come last with reversed arguments.
+ b = 12
+ call copy2(b+1, b)
+ if (b /= 13) stop 2
+
+end program p
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_5.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_5.f90
new file mode 100644
index 0000000..2f184bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_5.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/105012
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before the call to Y in the *.original dump, and the
+! initialization constant to be optimized away in the *.optimized dump,
+! despite the non-explicit interface if the subroutine with the INTENT(OUT)
+! is declared in the same file.
+
+SUBROUTINE Y (Z)
+ integer, intent(out) :: Z
+ Z = 42
+END SUBROUTINE Y
+PROGRAM TEST
+ integer :: X
+ X = 123456789
+ CALL Y (X)
+ if (X.ne.42) STOP 1
+END PROGRAM
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "x = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_6.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_6.f90
new file mode 100644
index 0000000..72fec3d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_6.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constant to be optimized away in the *.optimized dump,
+! in the case of an argument passed by reference to the caller.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer(kind=4), intent(out) :: a
+ a = 42
+ end subroutine foo
+ subroutine bar(b)
+ integer(kind=4) :: b
+ b = 123456789
+ call foo(b)
+ end subroutine bar
+end module x
+
+program main
+ use x
+ implicit none
+ integer(kind=4) :: c
+ call bar(c)
+ if (c /= 42) stop 1
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "\\*\\\(integer\\\(kind=4\\\) \\*\\\) b = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_7.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_7.f90
new file mode 100644
index 0000000..c2f2192
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_7.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constants to be optimized away in the *.optimized dump,
+! in the case of SAVE variables.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer, intent(out) :: a
+ a = 42
+ end subroutine foo
+end module x
+
+program main
+ use x
+ implicit none
+ integer :: c = 0
+
+ ! implicit SAVE attribute
+ c = 123456789
+ call foo(c)
+ if (c /= 42) stop 1
+
+ ! explicit SAVE attribute
+ call check_save_explicit
+
+contains
+ subroutine check_save_explicit
+ integer, save :: d
+ d = 987654321
+ call foo(d)
+ if (d /= 42) stop 2
+ end subroutine check_save_explicit
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+! { dg-final { scan-tree-dump "c = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump "d = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "987654321" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_8.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_8.f90
new file mode 100644
index 0000000..4336fce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_8.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constants to be optimized away in the *.optimized dump,
+! in the case of associate variables.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer, intent(out) :: a
+ a = 42
+ end subroutine foo
+end module x
+
+program main
+ use x
+ implicit none
+ integer :: c1, c2
+
+ c1 = 123456789
+ associate (d1 => c1)
+ call foo(d1)
+ if (d1 /= 42) stop 1
+ end associate
+ if (c1 /= 42) stop 2
+
+ c2 = 0
+ associate (d2 => c2)
+ d2 = 987654321
+ call foo(d2)
+ if (d2 /= 42) stop 3
+ end associate
+ if (c2 /= 42) stop 4
+
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+! { dg-final { scan-tree-dump "d1 = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump "\\*d2 = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "987654321" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_9.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_9.f90
new file mode 100644
index 0000000..0146dff
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_9.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constants to be optimized away in the *.optimized dump,
+! in the case of scalar allocatables and pointers.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer, intent(out) :: a
+ a = 42
+ end subroutine foo
+end module x
+
+program main
+ use x
+ implicit none
+ integer, allocatable :: ca
+ integer, target :: ct
+ integer, pointer :: cp
+
+ allocate(ca)
+ ca = 123456789
+ call foo(ca)
+ if (ca /= 42) stop 1
+ deallocate(ca)
+
+ ct = 987654321
+ cp => ct
+ call foo(cp)
+ if (ct /= 42) stop 2
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+! { dg-final { scan-tree-dump "\\*ca = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump "\\*cp = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "987654321" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_out_15.f90 b/gcc/testsuite/gfortran.dg/intent_out_15.f90
new file mode 100644
index 0000000..64334e6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_out_15.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/105012
+! The following case was triggering an ICE because of a clobber
+! on the DERFC function decl instead of its result.
+
+module error_function
+integer, parameter :: r8 = selected_real_kind(12) ! 8 byte real
+contains
+SUBROUTINE CALERF_r8(ARG, RESULT, JINT)
+ integer, parameter :: rk = r8
+ real(rk), intent(in) :: arg
+ real(rk), intent(out) :: result
+ IF (Y .LE. THRESH) THEN
+ END IF
+end SUBROUTINE CALERF_r8
+FUNCTION DERFC(X)
+ integer, parameter :: rk = r8 ! 8 byte real
+ real(rk), intent(in) :: X
+ real(rk) :: DERFC
+ CALL CALERF_r8(X, DERFC, JINT)
+END FUNCTION DERFC
+end module error_function
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "__result_derfc = {CLOBBER};" "original" } }
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 80c2bcb..55807fe 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -690,6 +690,10 @@ enum tree_index {
- TI_FLOATN_NX_TYPE_FIRST \
+ 1)
+ /* Type used by certain backends for __float128, which in C++ should be
+ distinct type from _Float128 for backwards compatibility reasons. */
+ TI_FLOAT128T_TYPE,
+
/* Put the complex types after their component types, so that in (sequential)
tree streaming we can assert that their component types have already been
handled (see tree-streamer.cc:record_common_node). */
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 513e0c8..84bef79 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -1227,29 +1227,30 @@ void
dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
{
edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
-
if (!pred_e)
return;
gimple *stmt = last_stmt (pred_e->src);
+ if (!stmt
+ || gimple_code (stmt) != GIMPLE_COND
+ || !assert_unreachable_fallthru_edge_p (pred_e))
+ return;
+
tree name;
- if (stmt
- && gimple_code (stmt) == GIMPLE_COND
- && (name = gimple_cond_lhs (stmt))
- && TREE_CODE (name) == SSA_NAME
- && assert_unreachable_fallthru_edge_p (pred_e)
- && all_uses_feed_or_dominated_by_stmt (name, stmt))
- {
- Value_Range r (TREE_TYPE (name));
+ gori_compute &gori = m_ranger->gori ();
+ FOR_EACH_GORI_EXPORT_NAME (gori, pred_e->src, name)
+ if (all_uses_feed_or_dominated_by_stmt (name, stmt))
+ {
+ Value_Range r (TREE_TYPE (name));
- if (m_ranger->range_on_edge (r, pred_e, name)
- && !r.varying_p ()
- && !r.undefined_p ())
- {
- set_range_info (name, r);
- maybe_set_nonzero_bits (pred_e, name);
- }
- }
+ if (m_ranger->range_on_edge (r, pred_e, name)
+ && !r.varying_p ()
+ && !r.undefined_p ())
+ {
+ set_range_info (name, r);
+ maybe_set_nonzero_bits (pred_e, name);
+ }
+ }
}
/* Record any equivalences created by the incoming edge to BB into
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index c5c8b68..b39c3c8 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -3608,13 +3608,13 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length,
tree type2 = NULL_TREE;
bool strict_overflow_p = false;
candidates.truncate (0);
- if (POINTER_TYPE_P (type1))
+ if (POINTER_TYPE_P (type1) || TREE_CODE (type1) == OFFSET_TYPE)
type1 = pointer_sized_int_node;
for (j = i; j; j = chains[j - 1])
{
tree type = TREE_TYPE (ranges[j - 1].exp);
strict_overflow_p |= ranges[j - 1].strict_overflow_p;
- if (POINTER_TYPE_P (type))
+ if (POINTER_TYPE_P (type) || TREE_CODE (type) == OFFSET_TYPE)
type = pointer_sized_int_node;
if ((b % 4) == 3)
{
@@ -3646,7 +3646,7 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length,
tree type = TREE_TYPE (ranges[j - 1].exp);
if (j == k)
continue;
- if (POINTER_TYPE_P (type))
+ if (POINTER_TYPE_P (type) || TREE_CODE (type) == OFFSET_TYPE)
type = pointer_sized_int_node;
if ((b % 4) == 3)
{
@@ -3677,10 +3677,20 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length,
op = r->exp;
continue;
}
- if (id == l || POINTER_TYPE_P (TREE_TYPE (op)))
+ if (id == l
+ || POINTER_TYPE_P (TREE_TYPE (op))
+ || TREE_CODE (TREE_TYPE (op)) == OFFSET_TYPE)
{
code = (b % 4) == 3 ? BIT_NOT_EXPR : NOP_EXPR;
tree type3 = id >= l ? type1 : pointer_sized_int_node;
+ if (code == BIT_NOT_EXPR
+ && TREE_CODE (TREE_TYPE (op)) == OFFSET_TYPE)
+ {
+ g = gimple_build_assign (make_ssa_name (type3),
+ NOP_EXPR, op);
+ gimple_seq_add_stmt_without_update (&seq, g);
+ op = gimple_assign_lhs (g);
+ }
g = gimple_build_assign (make_ssa_name (type3), code, op);
gimple_seq_add_stmt_without_update (&seq, g);
op = gimple_assign_lhs (g);
@@ -3688,6 +3698,7 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length,
tree type = TREE_TYPE (r->exp);
tree exp = r->exp;
if (POINTER_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE
|| (id >= l && !useless_type_conversion_p (type1, type)))
{
tree type3 = id >= l ? type1 : pointer_sized_int_node;
@@ -3705,7 +3716,7 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length,
op = gimple_assign_lhs (g);
}
type1 = TREE_TYPE (ranges[k - 1].exp);
- if (POINTER_TYPE_P (type1))
+ if (POINTER_TYPE_P (type1) || TREE_CODE (type1) == OFFSET_TYPE)
{
gimple *g
= gimple_build_assign (make_ssa_name (type1), NOP_EXPR, op);
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 4165cbd..756c14f 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9461,6 +9461,7 @@ build_common_tree_nodes (bool signed_char)
layout_type (FLOATN_NX_TYPE_NODE (i));
SET_TYPE_MODE (FLOATN_NX_TYPE_NODE (i), mode);
}
+ float128t_type_node = float128_type_node;
float_ptr_type_node = build_pointer_type (float_type_node);
double_ptr_type_node = build_pointer_type (double_type_node);
diff --git a/gcc/tree.h b/gcc/tree.h
index 266e24a..95285e4 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4302,6 +4302,10 @@ tree_strip_any_location_wrapper (tree exp)
#define float64x_type_node global_trees[TI_FLOAT64X_TYPE]
#define float128x_type_node global_trees[TI_FLOAT128X_TYPE]
+/* Type used by certain backends for __float128, which in C++ should be
+ distinct type from _Float128 for backwards compatibility reasons. */
+#define float128t_type_node global_trees[TI_FLOAT128T_TYPE]
+
#define float_ptr_type_node global_trees[TI_FLOAT_PTR_TYPE]
#define double_ptr_type_node global_trees[TI_DOUBLE_PTR_TYPE]
#define long_double_ptr_type_node global_trees[TI_LONG_DOUBLE_PTR_TYPE]
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 9ca4424..6154d73 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -258,15 +258,6 @@ frange::accept (const vrange_visitor &v) const
v.visit (*this);
}
-// Helper function to compare floats. Returns TRUE if op1 .CODE. op2
-// is nonzero.
-
-static inline bool
-tree_compare (tree_code code, tree op1, tree op2)
-{
- return !integer_zerop (fold_build2 (code, integer_type_node, op1, op2));
-}
-
// Flush denormal endpoints to the appropriate 0.0.
void
@@ -2939,6 +2930,19 @@ irange::set_nonzero_bits (const wide_int_ref &bits)
set_nonzero_bits (NULL);
return;
}
+ // If we have only one bit set in the mask, we can figure out the
+ // range immediately.
+ if (wi::popcount (bits) == 1)
+ {
+ bool has_zero = contains_p (build_zero_cst (type ()));
+ set (type (), bits, bits);
+ if (has_zero)
+ {
+ int_range<2> zero;
+ zero.set_zero (type ());
+ union_ (zero);
+ }
+ }
set_nonzero_bits (wide_int_to_tree (type (), bits));
}
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 413e54b..556e31a 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -117,6 +117,8 @@ class GTY((user)) irange : public vrange
public:
// In-place setters.
virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
+ void set (tree type, const wide_int_ref &, const wide_int_ref &,
+ value_range_kind = VR_RANGE);
virtual void set_nonzero (tree type) override;
virtual void set_zero (tree type) override;
virtual void set_nonnegative (tree type) override;
@@ -687,6 +689,13 @@ irange::varying_compatible_p () const
return true;
}
+inline void
+irange::set (tree type, const wide_int_ref &min, const wide_int_ref &max,
+ value_range_kind kind)
+{
+ set (wide_int_to_tree (type, min), wide_int_to_tree (type, max), kind);
+}
+
inline bool
vrange::varying_p () const
{