aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog126
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/Makefile.rtl1
-rw-r--r--gcc/analyzer/ChangeLog19
-rw-r--r--gcc/analyzer/exploded-graph.h2
-rw-r--r--gcc/analyzer/region-model-manager.cc5
-rw-r--r--gcc/analyzer/region-model.cc111
-rw-r--r--gcc/analyzer/region-model.h5
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.cc6
-rw-r--r--gcc/c-family/c-omp.cc9
-rw-r--r--gcc/c-family/c-pretty-print.cc6
-rw-r--r--gcc/cfgloop.cc13
-rw-r--r--gcc/combine.cc4
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.cc244
-rw-r--r--gcc/config/aarch64/aarch64.md60
-rw-r--r--gcc/config/aarch64/iterators.md3
-rw-r--r--gcc/config/gcn/gcn.cc2
-rw-r--r--gcc/config/i386/host-cygwin.cc16
-rw-r--r--gcc/config/rs6000/rs6000.cc6
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/constexpr.cc13
-rw-r--r--gcc/cp/pt.cc41
-rw-r--r--gcc/d/d-builtins.cc2
-rw-r--r--gcc/d/d-gimplify.cc71
-rw-r--r--gcc/d/d-target.cc33
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/README.md1
-rw-r--r--gcc/d/dmd/access.d10
-rw-r--r--gcc/d/dmd/astenums.d45
-rw-r--r--gcc/d/dmd/attrib.d58
-rw-r--r--gcc/d/dmd/blockexit.d79
-rw-r--r--gcc/d/dmd/canthrow.d85
-rw-r--r--gcc/d/dmd/constfold.d20
-rw-r--r--gcc/d/dmd/cparse.d206
-rw-r--r--gcc/d/dmd/cppmangle.d13
-rw-r--r--gcc/d/dmd/dcast.d12
-rw-r--r--gcc/d/dmd/dclass.d1
-rw-r--r--gcc/d/dmd/declaration.d10
-rw-r--r--gcc/d/dmd/denum.d3
-rw-r--r--gcc/d/dmd/dinterpret.d31
-rw-r--r--gcc/d/dmd/dscope.d3
-rw-r--r--gcc/d/dmd/dsymbol.d2
-rw-r--r--gcc/d/dmd/dsymbolsem.d25
-rw-r--r--gcc/d/dmd/dtemplate.d176
-rw-r--r--gcc/d/dmd/dtoh.d1
-rw-r--r--gcc/d/dmd/escape.d35
-rw-r--r--gcc/d/dmd/expression.d38
-rw-r--r--gcc/d/dmd/expression.h12
-rw-r--r--gcc/d/dmd/expressionsem.d110
-rw-r--r--gcc/d/dmd/func.d2
-rw-r--r--gcc/d/dmd/globals.d44
-rw-r--r--gcc/d/dmd/globals.h1
-rw-r--r--gcc/d/dmd/hdrgen.d11
-rw-r--r--gcc/d/dmd/id.d6
-rw-r--r--gcc/d/dmd/json.d3
-rw-r--r--gcc/d/dmd/mtype.d152
-rw-r--r--gcc/d/dmd/mtype.h1
-rw-r--r--gcc/d/dmd/nogc.d1
-rw-r--r--gcc/d/dmd/nspace.d1
-rw-r--r--gcc/d/dmd/objc.d58
-rw-r--r--gcc/d/dmd/opover.d10
-rw-r--r--gcc/d/dmd/optimize.d4
-rw-r--r--gcc/d/dmd/parse.d605
-rw-r--r--gcc/d/dmd/parsetimevisitor.d1
-rw-r--r--gcc/d/dmd/root/README.md1
-rw-r--r--gcc/d/dmd/root/optional.d2
-rw-r--r--gcc/d/dmd/sideeffect.d28
-rw-r--r--gcc/d/dmd/statement.d1
-rw-r--r--gcc/d/dmd/statement.h2
-rw-r--r--gcc/d/dmd/statementsem.d67
-rw-r--r--gcc/d/dmd/staticcond.d14
-rw-r--r--gcc/d/dmd/target.d24
-rw-r--r--gcc/d/dmd/target.h7
-rw-r--r--gcc/d/dmd/template.h1
-rw-r--r--gcc/d/dmd/tokens.d5
-rw-r--r--gcc/d/dmd/tokens.h1
-rw-r--r--gcc/d/dmd/traits.d39
-rw-r--r--gcc/d/dmd/transitivevisitor.d6
-rw-r--r--gcc/d/dmd/typesem.d6
-rw-r--r--gcc/d/dmd/visitor.h2
-rw-r--r--gcc/d/expr.cc8
-rw-r--r--gcc/d/types.cc77
-rw-r--r--gcc/doc/invoke.texi24
-rw-r--r--gcc/fold-const.cc40
-rw-r--r--gcc/fold-const.h1
-rw-r--r--gcc/fortran/ChangeLog24
-rw-r--r--gcc/fortran/expr.cc8
-rw-r--r--gcc/fortran/trans-openmp.cc49
-rw-r--r--gcc/gimple-fold.cc4
-rw-r--r--gcc/gimple-loop-jam.cc10
-rw-r--r--gcc/gimple-range-fold.cc12
-rw-r--r--gcc/gimple-range-gori.cc96
-rw-r--r--gcc/gimple-range-gori.h2
-rw-r--r--gcc/gimplify.cc17
-rw-r--r--gcc/go/ChangeLog7
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/omp-low.cc9
-rw-r--r--gcc/simplify-rtx.cc2
-rw-r--r--gcc/testsuite/ChangeLog152
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-31.c11
-rw-r--r--gcc/testsuite/c-c++-common/pr104505.c12
-rw-r--r--gcc/testsuite/c-c++-common/torture/pr104497.c12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp2.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/ttp2.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C13
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent21.C9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr102692-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104524.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/pr102692.c (renamed from gcc/testsuite/gcc.dg/analyzer/pr102692.c)4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr104510.c12
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr104517.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr104511.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr104522.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr104526.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr104544.c19
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr104519.c10
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr104543.c21
-rw-r--r--gcc/testsuite/gcc.target/aarch64/atomic-inst-cas.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/bic-bitmask-1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_14.c89
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_14.h50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_15.c137
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_16.c133
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_17.c120
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_18.c123
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_19.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_1.c149
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_2.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_3.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_4.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_5.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_6.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/max_plus_7.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_1.c149
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_2.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_3.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_4.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_5.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_6.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/min_plus_7.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr100056.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/shl-combine-2.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/shl-combine-3.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/shl-combine-4.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/shl-combine-5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/store_v2vec_lanes.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xtn-combine-1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xtn-combine-2.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xtn-combine-3.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xtn-combine-4.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xtn-combine-5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/xtn-combine-6.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr104448.c9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/htm-1.c9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr104253.c156
-rw-r--r--gcc/testsuite/gdc.test/compilable/casttuple.d31
-rw-r--r--gcc/testsuite/gdc.test/compilable/deprecated_override.d97
-rw-r--r--gcc/testsuite/gdc.test/compilable/extra-files/header1.d6
-rw-r--r--gcc/testsuite/gdc.test/compilable/fix17635.d16
-rw-r--r--gcc/testsuite/gdc.test/compilable/fix22291.d134
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/cstuff3.c6
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/imp22625.c1
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/imp22665.c1
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/test22685b.d5
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/test22685c.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/issue22130.d12
-rw-r--r--gcc/testsuite/gdc.test/compilable/noreturn1.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/test13008.d6
-rw-r--r--gcc/testsuite/gdc.test/compilable/test18771.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/test19609.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/test19873.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/test21299a.d2
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22619.d11
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22625.d4
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22646.d21
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22665.d22
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22676.d25
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22685.d11
-rw-r--r--gcc/testsuite/gdc.test/compilable/test55.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/testcstuff3.d4
-rw-r--r--gcc/testsuite/gdc.test/compilable/testos.d7
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/b16967.d (renamed from gcc/testsuite/gdc.test/compilable/b16967.d)5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/bug5096.d14
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/bug9631.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/casttuple.d25
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d26
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d28
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d12
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d12
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag11819b.d38
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag13333.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag13942.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag16271.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag16977.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag19225.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag8101.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag8648.d6
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag8684.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag9004.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag9420.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diagin.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/dip25.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail10964.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail11453a.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail11453b.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail11653.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail12744.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail132.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail14669.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail162.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18417.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail196.d33
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19609.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail19897.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail207.d5
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail20730b.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail21830.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail21831.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail21832.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail220.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22035.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22084.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22133.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22144.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail22749.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail236.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail276.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail4269e.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail59.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail60.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail8009.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail95.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fix17635.d23
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice11856_0.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice14130.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice14907.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice6538.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice9284.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/imp18554.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/imports/imp22749.c4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/issue21936.d32
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/noreturn.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/noreturn2.d51
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/objc_class2.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/objc_class3.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/objc_non_objc_base.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/reg6769.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/reserved_version.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/retscope5.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test15191.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test16188.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test16589.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test17284.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test17450.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test18554.d24
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test19107.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test19193.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21912.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22298.d30
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22541.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22709.d29
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test3818.d27
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test9701.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test9701b.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/traits_parameters.d10
-rw-r--r--gcc/testsuite/gdc.test/runnable/a18.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/a19.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/b26.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/class_opCmp.d25
-rw-r--r--gcc/testsuite/gdc.test/runnable/fix22624.d19
-rw-r--r--gcc/testsuite/gdc.test/runnable/ice15138.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/ice15176.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/ice15200.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/imports/imp22624.c6
-rw-r--r--gcc/testsuite/gdc.test/runnable/issue16995.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link10425.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link11069b.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link11395.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link12010.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link13394.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link13400.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link13415.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link14588.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link14814.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link15017.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link7745.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link8023.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/link9571.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/linktypeinfo.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/noreturn1.d152
-rw-r--r--gcc/testsuite/gdc.test/runnable/test11039.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test11239.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test11447a.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test11447b.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test11447c.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test11863.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test14901.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test18868.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test27.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test29.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test31.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test32.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test38.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test46.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test49.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test57.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test7494.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/test8997.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/testmod1.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/tls_dup.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable_cxx/cppa.d3
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/depend-4.f90261
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/depend-5.f9082
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/depend-6.f90259
-rw-r--r--gcc/testsuite/gfortran.dg/pr104211.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/pr104528.f44
-rw-r--r--gcc/tree-ssa-dse.cc8
-rw-r--r--gcc/tree-ssa-forwprop.cc9
-rw-r--r--gcc/tree-ssa-loop-niter.cc16
-rw-r--r--gcc/tree-ssa.cc2
-rw-r--r--gcc/tree-ssa.h1
-rw-r--r--gcc/tree-vect-slp.cc77
-rw-r--r--gcc/tree-vectorizer.h35
331 files changed, 6157 insertions, 1282 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a3e17e0..f3de0c1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,129 @@
+2022-02-15 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/104526
+ * gimple-range-fold.cc (fold_using_range::range_of_cond_expr): Call
+ new routine.
+ * gimple-range-gori.cc (range_def_chain::get_def_chain): Force a build
+ of dependency chain if there isn't one.
+ (gori_compute::condexpr_adjust): New.
+ * gimple-range-gori.h (class gori_compute): New prototype.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/100874
+ * config/aarch64/aarch64-protos.h (aarch64_maxmin_plus_const):
+ Declare.
+ * config/aarch64/aarch64.cc (aarch64_maxmin_plus_const): New function.
+ * config/aarch64/aarch64.md (*aarch64_minmax_plus): New pattern.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-vectorizer.h (vect_scalar_ops_slice): New struct.
+ (vect_scalar_ops_slice_hash): Likewise.
+ (vect_scalar_ops_slice::op): New function.
+ * tree-vect-slp.cc (vect_scalar_ops_slice::all_same_p): New function.
+ (vect_scalar_ops_slice_hash::hash): Likewise.
+ (vect_scalar_ops_slice_hash::equal): Likewise.
+ (vect_prologue_cost_for_slp): Check for duplicate vectors.
+ * config/aarch64/aarch64.cc
+ (aarch64_vector_costs::m_stp_sequence_cost): New member variable.
+ (aarch64_aligned_constant_offset_p): New function.
+ (aarch64_stp_sequence_cost): Likewise.
+ (aarch64_vector_costs::add_stmt_cost): Handle new STP heuristic.
+ (aarch64_vector_costs::finish_cost): Likewise.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-vect-slp.cc (vect_bb_vectorization_profitable_p): Fix
+ use after free.
+
+2022-02-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104543
+ * gimple-loop-jam.cc (unroll_jam_possible_p): Check outer loop exits
+ come after the inner loop.
+
+2022-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/104536
+ * config/i386/host-cygwin.cc (cygwin_gt_pch_get_address): Use
+ cannot instead of can%'t in diagnostics. Formatting fixes.
+
+2022-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/104522
+ * fold-const.h (native_interpret_real): Declare.
+ * fold-const.cc (native_interpret_real): No longer static. Don't
+ perform MODE_COMPOSITE_P verification here.
+ (native_interpret_expr) <case REAL_TYPE>: But perform it here instead
+ for all modes.
+ * gimple-fold.cc (clear_padding_type): Call native_interpret_real
+ instead of native_interpret_expr.
+ * simplify-rtx.cc (simplify_immed_subreg): Perform the native_encode_rtx
+ and comparison verification for all FLOAT_MODE_P modes, not just
+ MODE_COMPOSITE_P.
+
+2022-02-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104519
+ * fold-const.cc (multiple_of_p): Remove never true condition.
+ * tree-ssa-loop-niter.cc (number_of_iterations_ne): Use
+ the appropriate types for determining whether the difference
+ of final and base is a multiple of the step.
+
+2022-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/104517
+ * omp-low.cc (task_cpyfns): New variable.
+ (delete_omp_context): Don't call finalize_task_copyfn from here.
+ (create_task_copyfn): Push task_stmt into task_cpyfns.
+ (execute_lower_omp): Call finalize_task_copyfn here on entries from
+ task_cpyfns vector and release the vector.
+
+2022-02-14 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/104355
+ * doc/invoke.texi (-Warray-bounds): Update documentation.
+
+2022-02-14 Michael Meissner <meissner@the-meissners.org>
+
+ PR target/104253
+ * config/rs6000/rs6000.cc (init_float128_ibm): Update the
+ conversion functions used to convert IFmode types.
+
+2022-02-14 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn.cc (gcn_expand_reduc_scalar): Use force_reg.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104528
+ * tree-ssa.h (find_released_ssa_name): Declare.
+ * tree-ssa.cc (find_released_ssa_name): Export.
+ * cfgloop.cc (verify_loop_structure): Look for released
+ SSA names in loops nb_iterations.
+ * tree-ssa-dse.cc (pass_dse::execute): Release number of iteration
+ estimates.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104511
+ * tree-ssa-forwprop.cc (simplify_vector_constructor): Avoid
+ touching DFP <-> FP conversions.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/104497
+ * gimplify.cc (gimplify_compound_lval): Make sure the
+ base is a non-register if needed and possible.
+
+2022-02-13 liuhongt <hongtao.liu@intel.com>
+
+ PR target/103771
+ * match.pd (cond_expr_convert_p): New match.
+ * tree-vect-patterns.cc (gimple_cond_expr_convert_p): Declare.
+ (vect_recog_cond_expr_convert_pattern): New.
+
2022-02-12 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/104449
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 35b6375..07f9f51 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220213
+20220216
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 3e72eb7..cae3536 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2022-02-13 Maciej W. Rozycki <macro@orcam.me.uk>
+
+ PR ada/98724
+ PR ada/97504
+ * Makefile.rtl (LIBGNAT_TARGET_PAIRS) <alpha*-*-linux*>: Use
+ wraplf version of Aux_Long_Long_Float.
+
2022-01-31 Pierre-Marie de Rodat <derodat@adacore.com>
* doc/share/conf.py: Remove spurious call to ".decode()".
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 6d60aea..aaf853e 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2559,6 +2559,7 @@ endif
ifeq ($(strip $(filter-out alpha% linux%,$(target_cpu) $(target_os))),)
LIBGNAT_TARGET_PAIRS = \
a-intnam.ads<libgnarl/a-intnam__linux.ads \
+ a-nallfl.ads<libgnat/a-nallfl__wraplf.ads \
s-inmaop.adb<libgnarl/s-inmaop__posix.adb \
s-intman.adb<libgnarl/s-intman__posix.adb \
s-linux.ads<libgnarl/s-linux__alpha.ads \
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index f5d1243..cab27465 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,22 @@
+2022-02-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/104524
+ * region-model-manager.cc
+ (region_model_manager::maybe_fold_sub_svalue): Only call
+ get_or_create_cast if type is non-NULL.
+
+2022-02-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/102692
+ * exploded-graph.h (impl_region_model_context::get_stmt): New.
+ * region-model.cc: Include "gimple-ssa.h", "tree-phinodes.h",
+ "tree-ssa-operands.h", and "ssa-iterators.h".
+ (within_short_circuited_stmt_p): New.
+ (region_model::check_for_poison): Don't warn about uninit values
+ if within_short_circuited_stmt_p.
+ * region-model.h (region_model_context::get_stmt): New vfunc.
+ (noop_region_model_context::get_stmt): New.
+
2022-02-11 David Malcolm <dmalcolm@redhat.com>
PR analyzer/104274
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index 1854193..1f52725 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -90,6 +90,8 @@ class impl_region_model_context : public region_model_context
const state_machine **out_sm,
unsigned *out_sm_idx) FINAL OVERRIDE;
+ const gimple *get_stmt () const OVERRIDE { return m_stmt; }
+
exploded_graph *m_eg;
log_user m_logger;
exploded_node *m_enode_for_diag;
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index d7156c5..917af22 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -771,7 +771,7 @@ region_model_manager::maybe_fold_sub_svalue (tree type,
if (unary->get_op () == NOP_EXPR
|| unary->get_op () == VIEW_CONVERT_EXPR)
if (tree cst = unary->get_arg ()->maybe_get_constant ())
- if (zerop (cst))
+ if (zerop (cst) && type)
{
const svalue *cst_sval
= get_or_create_constant_svalue (cst);
@@ -786,7 +786,8 @@ region_model_manager::maybe_fold_sub_svalue (tree type,
/* If we have a concrete 1-byte access within the parent region... */
byte_range subregion_bytes (0, 0);
if (subregion->get_relative_concrete_byte_range (&subregion_bytes)
- && subregion_bytes.m_size_in_bytes == 1)
+ && subregion_bytes.m_size_in_bytes == 1
+ && type)
{
/* ...then attempt to get that char from the STRING_CST. */
HOST_WIDE_INT hwi_start_byte
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index e659cf0..69e8fa7 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -68,6 +68,10 @@ along with GCC; see the file COPYING3. If not see
#include "stor-layout.h"
#include "attribs.h"
#include "tree-object-size.h"
+#include "gimple-ssa.h"
+#include "tree-phinodes.h"
+#include "tree-ssa-operands.h"
+#include "ssa-iterators.h"
#if ENABLE_ANALYZER
@@ -829,6 +833,108 @@ region_model::get_gassign_result (const gassign *assign,
}
}
+/* Workaround for discarding certain false positives from
+ -Wanalyzer-use-of-uninitialized-value
+ of the form:
+ ((A OR-IF B) OR-IF C)
+ and:
+ ((A AND-IF B) AND-IF C)
+ where evaluating B is redundant, but could involve simple accesses of
+ uninitialized locals.
+
+ When optimization is turned on the FE can immediately fold compound
+ conditionals. Specifically, c_parser_condition parses this condition:
+ ((A OR-IF B) OR-IF C)
+ and calls c_fully_fold on the condition.
+ Within c_fully_fold, fold_truth_andor is called, which bails when
+ optimization is off, but if any optimization is turned on can convert the
+ ((A OR-IF B) OR-IF C)
+ into:
+ ((A OR B) OR_IF C)
+ for sufficiently simple B
+ i.e. the inner OR-IF becomes an OR.
+ At gimplification time the inner OR becomes BIT_IOR_EXPR (in gimplify_expr),
+ giving this for the inner condition:
+ tmp = A | B;
+ if (tmp)
+ thus effectively synthesizing a redundant access of B when optimization
+ is turned on, when compared to:
+ if (A) goto L1; else goto L4;
+ L1: if (B) goto L2; else goto L4;
+ L2: if (C) goto L3; else goto L4;
+ for the unoptimized case.
+
+ Return true if CTXT appears to be handling such a short-circuitable stmt,
+ such as the def-stmt for B for the:
+ tmp = A | B;
+ case above, for the case where A is true and thus B would have been
+ short-circuited without optimization, using MODEL for the value of A. */
+
+static bool
+within_short_circuited_stmt_p (const region_model *model,
+ region_model_context *ctxt)
+{
+ gcc_assert (ctxt);
+ const gimple *curr_stmt = ctxt->get_stmt ();
+ if (curr_stmt == NULL)
+ return false;
+
+ /* We must have an assignment to a temporary of _Bool type. */
+ const gassign *assign_stmt = dyn_cast <const gassign *> (curr_stmt);
+ if (!assign_stmt)
+ return false;
+ tree lhs = gimple_assign_lhs (assign_stmt);
+ if (TREE_TYPE (lhs) != boolean_type_node)
+ return false;
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return false;
+ if (SSA_NAME_VAR (lhs) != NULL_TREE)
+ return false;
+
+ /* The temporary bool must be used exactly once: as the second arg of
+ a BIT_IOR_EXPR or BIT_AND_EXPR. */
+ use_operand_p use_op;
+ gimple *use_stmt;
+ if (!single_imm_use (lhs, &use_op, &use_stmt))
+ return false;
+ const gassign *use_assign = dyn_cast <const gassign *> (use_stmt);
+ if (!use_assign)
+ return false;
+ enum tree_code op = gimple_assign_rhs_code (use_assign);
+ if (!(op == BIT_IOR_EXPR ||op == BIT_AND_EXPR))
+ return false;
+ if (!(gimple_assign_rhs1 (use_assign) != lhs
+ && gimple_assign_rhs2 (use_assign) == lhs))
+ return false;
+
+ /* The first arg of the bitwise stmt must have a known value in MODEL
+ that implies that the value of the second arg doesn't matter, i.e.
+ 1 for bitwise or, 0 for bitwise and. */
+ tree other_arg = gimple_assign_rhs1 (use_assign);
+ /* Use a NULL ctxt here to avoid generating warnings. */
+ const svalue *other_arg_sval = model->get_rvalue (other_arg, NULL);
+ tree other_arg_cst = other_arg_sval->maybe_get_constant ();
+ if (!other_arg_cst)
+ return false;
+ switch (op)
+ {
+ default:
+ gcc_unreachable ();
+ case BIT_IOR_EXPR:
+ if (zerop (other_arg_cst))
+ return false;
+ break;
+ case BIT_AND_EXPR:
+ if (!zerop (other_arg_cst))
+ return false;
+ break;
+ }
+
+ /* All tests passed. We appear to be in a stmt that generates a boolean
+ temporary with a value that won't matter. */
+ return true;
+}
+
/* Check for SVAL being poisoned, adding a warning to CTXT.
Return SVAL, or, if a warning is added, another value, to avoid
repeatedly complaining about the same poisoned value in followup code. */
@@ -852,6 +958,11 @@ region_model::check_for_poison (const svalue *sval,
&& is_empty_type (sval->get_type ()))
return sval;
+ /* Special case to avoid certain false positives. */
+ if (pkind == POISON_KIND_UNINIT
+ && within_short_circuited_stmt_p (this, ctxt))
+ return sval;
+
/* If we have an SSA name for a temporary, we don't want to print
'<unknown>'.
Poisoned values are shared by type, and so we can't reconstruct
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 46cf37e..c2c89a2 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -930,6 +930,9 @@ class region_model_context
virtual bool get_taint_map (sm_state_map **out_smap,
const state_machine **out_sm,
unsigned *out_sm_idx) = 0;
+
+ /* Get the current statement, if any. */
+ virtual const gimple *get_stmt () const = 0;
};
/* A "do nothing" subclass of region_model_context. */
@@ -980,6 +983,8 @@ public:
{
return false;
}
+
+ const gimple *get_stmt () const OVERRIDE { return NULL; }
};
/* A subclass of region_model_context for determining if operations fail
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 78f6f6f..340e2c0 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR c/104505
+ * c-pretty-print.cc (c_pretty_printer::postfix_expression): Handle
+ internal function calls.
+
2022-02-11 Richard Biener <rguenther@suse.de>
* c-attribs.cc (c_common_attribute_table): Add entry for
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index bf0749b..7203d76 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -3174,7 +3174,11 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr,
else if (real1 && real2
&& (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop0)))
|| DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (primop1)))))
- return NULL_TREE;
+ {
+ type = *restype_ptr;
+ primop0 = op0;
+ primop1 = op1;
+ }
else if (real1 && real2
&& (TYPE_PRECISION (TREE_TYPE (primop0))
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index f5314d6..cd9d866 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -353,8 +353,13 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
}
bool save = in_late_binary_op;
in_late_binary_op = true;
- x = build_modify_expr (loc, blhs ? blhs : lhs, NULL_TREE, opcode,
- loc, rhs, NULL_TREE);
+ if ((opcode == MIN_EXPR || opcode == MAX_EXPR)
+ && build_binary_op (loc, LT_EXPR, blhs ? blhs : lhs, rhs,
+ true) == error_mark_node)
+ x = error_mark_node;
+ else
+ x = build_modify_expr (loc, blhs ? blhs : lhs, NULL_TREE, opcode,
+ loc, rhs, NULL_TREE);
in_late_binary_op = save;
if (x == error_mark_node)
return error_mark_node;
diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index ceedaea..dac1775 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "selftest.h"
#include "langhooks.h"
#include "options.h"
+#include "internal-fn.h"
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
@@ -1601,7 +1602,10 @@ c_pretty_printer::postfix_expression (tree e)
{
call_expr_arg_iterator iter;
tree arg;
- postfix_expression (CALL_EXPR_FN (e));
+ if (CALL_EXPR_FN (e) != NULL_TREE)
+ postfix_expression (CALL_EXPR_FN (e));
+ else
+ pp_string (this, internal_fn_name (CALL_EXPR_IFN (e)));
pp_c_left_paren (this);
FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
{
diff --git a/gcc/cfgloop.cc b/gcc/cfgloop.cc
index 78fd6d5..5ffcc77 100644
--- a/gcc/cfgloop.cc
+++ b/gcc/cfgloop.cc
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "gimple-iterator.h"
#include "dumpfile.h"
+#include "tree-ssa.h"
+#include "tree-pretty-print.h"
static void flow_loops_cfg_dump (FILE *);
@@ -1561,6 +1563,17 @@ verify_loop_structure (void)
err = 1;
}
}
+
+ /* Check cached number of iterations for released SSA names. */
+ tree ref;
+ if (loop->nb_iterations
+ && (ref = walk_tree (&loop->nb_iterations,
+ find_released_ssa_name, NULL, NULL)))
+ {
+ error ("loop %d%'s number of iterations %qE references the"
+ " released SSA name %qE", i, loop->nb_iterations, ref);
+ err = 1;
+ }
}
/* Check irreducible loops. */
diff --git a/gcc/combine.cc b/gcc/combine.cc
index c4c5444..8f06ee0 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -4223,10 +4223,12 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
for (rtx_insn *insn = NEXT_INSN (i3);
!done
&& insn
- && NONDEBUG_INSN_P (insn)
+ && INSN_P (insn)
&& BLOCK_FOR_INSN (insn) == this_basic_block;
insn = NEXT_INSN (insn))
{
+ if (DEBUG_INSN_P (insn))
+ continue;
struct insn_link *link;
FOR_EACH_LOG_LINK (link, insn)
if (link->insn == i3 && link->regno == regno)
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 392efa0..d0e78d6 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -939,6 +939,7 @@ bool aarch64_legitimate_address_p (machine_mode, rtx, bool,
aarch64_addr_query_type = ADDR_QUERY_M);
machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx);
rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx);
+bool aarch64_maxmin_plus_const (rtx_code, rtx *, bool);
rtx aarch64_load_tp (rtx);
void aarch64_expand_compare_and_swap (rtx op[]);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index e3f18fb..37ed22b 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -3781,6 +3781,110 @@ aarch64_gen_compare_reg_maybe_ze (RTX_CODE code, rtx x, rtx y,
return aarch64_gen_compare_reg (code, x, y);
}
+/* Consider the operation:
+
+ OPERANDS[0] = CODE (OPERANDS[1], OPERANDS[2]) + OPERANDS[3]
+
+ where:
+
+ - CODE is [SU]MAX or [SU]MIN
+ - OPERANDS[2] and OPERANDS[3] are constant integers
+ - OPERANDS[3] is a positive or negative shifted 12-bit immediate
+ - all operands have mode MODE
+
+ Decide whether it is possible to implement the operation using:
+
+ SUBS <tmp>, OPERANDS[1], -OPERANDS[3]
+ or
+ ADDS <tmp>, OPERANDS[1], OPERANDS[3]
+
+ followed by:
+
+ <insn> OPERANDS[0], <tmp>, [wx]zr, <cond>
+
+ where <insn> is one of CSEL, CSINV or CSINC. Return true if so.
+ If GENERATE_P is true, also update OPERANDS as follows:
+
+ OPERANDS[4] = -OPERANDS[3]
+ OPERANDS[5] = the rtl condition representing <cond>
+ OPERANDS[6] = <tmp>
+ OPERANDS[7] = 0 for CSEL, -1 for CSINV or 1 for CSINC. */
+bool
+aarch64_maxmin_plus_const (rtx_code code, rtx *operands, bool generate_p)
+{
+ signop sgn = (code == UMAX || code == UMIN ? UNSIGNED : SIGNED);
+ rtx dst = operands[0];
+ rtx maxmin_op = operands[2];
+ rtx add_op = operands[3];
+ machine_mode mode = GET_MODE (dst);
+
+ /* max (x, y) - z == (x >= y + 1 ? x : y) - z
+ == (x >= y ? x : y) - z
+ == (x > y ? x : y) - z
+ == (x > y - 1 ? x : y) - z
+
+ min (x, y) - z == (x <= y - 1 ? x : y) - z
+ == (x <= y ? x : y) - z
+ == (x < y ? x : y) - z
+ == (x < y + 1 ? x : y) - z
+
+ Check whether z is in { y - 1, y, y + 1 } and pick the form(s) for
+ which x is compared with z. Set DIFF to y - z. Thus the supported
+ combinations are as follows, with DIFF being the value after the ":":
+
+ max (x, y) - z == x >= y + 1 ? x - (y + 1) : -1 [z == y + 1]
+ == x >= y ? x - y : 0 [z == y]
+ == x > y ? x - y : 0 [z == y]
+ == x > y - 1 ? x - (y - 1) : 1 [z == y - 1]
+
+ min (x, y) - z == x <= y - 1 ? x - (y - 1) : 1 [z == y - 1]
+ == x <= y ? x - y : 0 [z == y]
+ == x < y ? x - y : 0 [z == y]
+ == x < y + 1 ? x - (y + 1) : -1 [z == y + 1]. */
+ auto maxmin_val = rtx_mode_t (maxmin_op, mode);
+ auto add_val = rtx_mode_t (add_op, mode);
+ auto sub_val = wi::neg (add_val);
+ auto diff = wi::sub (maxmin_val, sub_val);
+ if (!(diff == 0
+ || (diff == 1 && wi::gt_p (maxmin_val, sub_val, sgn))
+ || (diff == -1 && wi::lt_p (maxmin_val, sub_val, sgn))))
+ return false;
+
+ if (!generate_p)
+ return true;
+
+ rtx_code cmp;
+ switch (code)
+ {
+ case SMAX:
+ cmp = diff == 1 ? GT : GE;
+ break;
+ case UMAX:
+ cmp = diff == 1 ? GTU : GEU;
+ break;
+ case SMIN:
+ cmp = diff == -1 ? LT : LE;
+ break;
+ case UMIN:
+ cmp = diff == -1 ? LTU : LEU;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ rtx cc = gen_rtx_REG (CCmode, CC_REGNUM);
+
+ operands[4] = immed_wide_int_const (sub_val, mode);
+ operands[5] = gen_rtx_fmt_ee (cmp, VOIDmode, cc, const0_rtx);
+ if (can_create_pseudo_p ())
+ operands[6] = gen_reg_rtx (mode);
+ else
+ operands[6] = dst;
+ operands[7] = immed_wide_int_const (diff, mode);
+
+ return true;
+}
+
+
/* Build the SYMBOL_REF for __tls_get_addr. */
static GTY(()) rtx tls_get_addr_libfunc;
@@ -14932,6 +15036,31 @@ private:
- If M_VEC_FLAGS & VEC_ANY_SVE is nonzero then we're costing SVE code. */
unsigned int m_vec_flags = 0;
+ /* At the moment, we do not model LDP and STP in the vector and scalar costs.
+ This means that code such as:
+
+ a[0] = x;
+ a[1] = x;
+
+ will be costed as two scalar instructions and two vector instructions
+ (a scalar_to_vec and an unaligned_store). For SLP, the vector form
+ wins if the costs are equal, because of the fact that the vector costs
+ include constant initializations whereas the scalar costs don't.
+ We would therefore tend to vectorize the code above, even though
+ the scalar version can use a single STP.
+
+ We should eventually fix this and model LDP and STP in the main costs;
+ see the comment in aarch64_sve_adjust_stmt_cost for some of the problems.
+ Until then, we look specifically for code that does nothing more than
+ STP-like operations. We cost them on that basis in addition to the
+ normal latency-based costs.
+
+ If the scalar or vector code could be a sequence of STPs +
+ initialization, this variable counts the cost of the sequence,
+ with 2 units per instruction. The variable is ~0U for other
+ kinds of code. */
+ unsigned int m_stp_sequence_cost = 0;
+
/* On some CPUs, SVE and Advanced SIMD provide the same theoretical vector
throughput, such as 4x128 Advanced SIMD vs. 2x256 SVE. In those
situations, we try to predict whether an Advanced SIMD implementation
@@ -15724,6 +15853,104 @@ aarch64_vector_costs::count_ops (unsigned int count, vect_cost_for_stmt kind,
}
}
+/* Return true if STMT_INFO contains a memory access and if the constant
+ component of the memory address is aligned to SIZE bytes. */
+static bool
+aarch64_aligned_constant_offset_p (stmt_vec_info stmt_info,
+ poly_uint64 size)
+{
+ if (!STMT_VINFO_DATA_REF (stmt_info))
+ return false;
+
+ if (auto first_stmt = DR_GROUP_FIRST_ELEMENT (stmt_info))
+ stmt_info = first_stmt;
+ tree constant_offset = DR_INIT (STMT_VINFO_DATA_REF (stmt_info));
+ /* Needed for gathers & scatters, for example. */
+ if (!constant_offset)
+ return false;
+
+ return multiple_p (wi::to_poly_offset (constant_offset), size);
+}
+
+/* Check if a scalar or vector stmt could be part of a region of code
+ that does nothing more than store values to memory, in the scalar
+ case using STP. Return the cost of the stmt if so, counting 2 for
+ one instruction. Return ~0U otherwise.
+
+ The arguments are a subset of those passed to add_stmt_cost. */
+unsigned int
+aarch64_stp_sequence_cost (unsigned int count, vect_cost_for_stmt kind,
+ stmt_vec_info stmt_info, tree vectype)
+{
+ /* Code that stores vector constants uses a vector_load to create
+ the constant. We don't apply the heuristic to that case for two
+ main reasons:
+
+ - At the moment, STPs are only formed via peephole2, and the
+ constant scalar moves would often come between STRs and so
+ prevent STP formation.
+
+ - The scalar code also has to load the constant somehow, and that
+ isn't costed. */
+ switch (kind)
+ {
+ case scalar_to_vec:
+ /* Count 2 insns for a GPR->SIMD dup and 1 insn for a FPR->SIMD dup. */
+ return (FLOAT_TYPE_P (vectype) ? 2 : 4) * count;
+
+ case vec_construct:
+ if (FLOAT_TYPE_P (vectype))
+ /* Count 1 insn for the maximum number of FP->SIMD INS
+ instructions. */
+ return (vect_nunits_for_cost (vectype) - 1) * 2 * count;
+
+ /* Count 2 insns for a GPR->SIMD move and 2 insns for the
+ maximum number of GPR->SIMD INS instructions. */
+ return vect_nunits_for_cost (vectype) * 4 * count;
+
+ case vector_store:
+ case unaligned_store:
+ /* Count 1 insn per vector if we can't form STP Q pairs. */
+ if (aarch64_sve_mode_p (TYPE_MODE (vectype)))
+ return count * 2;
+ if (aarch64_tune_params.extra_tuning_flags
+ & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS)
+ return count * 2;
+
+ if (stmt_info)
+ {
+ /* Assume we won't be able to use STP if the constant offset
+ component of the address is misaligned. ??? This could be
+ removed if we formed STP pairs earlier, rather than relying
+ on peephole2. */
+ auto size = GET_MODE_SIZE (TYPE_MODE (vectype));
+ if (!aarch64_aligned_constant_offset_p (stmt_info, size))
+ return count * 2;
+ }
+ return CEIL (count, 2) * 2;
+
+ case scalar_store:
+ if (stmt_info && STMT_VINFO_DATA_REF (stmt_info))
+ {
+ /* Check for a mode in which STP pairs can be formed. */
+ auto size = GET_MODE_SIZE (TYPE_MODE (aarch64_dr_type (stmt_info)));
+ if (maybe_ne (size, 4) && maybe_ne (size, 8))
+ return ~0U;
+
+ /* Assume we won't be able to use STP if the constant offset
+ component of the address is misaligned. ??? This could be
+ removed if we formed STP pairs earlier, rather than relying
+ on peephole2. */
+ if (!aarch64_aligned_constant_offset_p (stmt_info, size))
+ return ~0U;
+ }
+ return count;
+
+ default:
+ return ~0U;
+ }
+}
+
unsigned
aarch64_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
stmt_vec_info stmt_info, tree vectype,
@@ -15747,6 +15974,14 @@ aarch64_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
m_analyzed_vinfo = true;
}
+ /* Apply the heuristic described above m_stp_sequence_cost. */
+ if (m_stp_sequence_cost != ~0U)
+ {
+ uint64_t cost = aarch64_stp_sequence_cost (count, kind,
+ stmt_info, vectype);
+ m_stp_sequence_cost = MIN (m_stp_sequence_cost + cost, ~0U);
+ }
+
/* Try to get a more accurate cost by looking at STMT_INFO instead
of just looking at KIND. */
if (stmt_info && aarch64_use_new_vector_costs_p ())
@@ -16017,6 +16252,15 @@ aarch64_vector_costs::finish_cost (const vector_costs *uncast_scalar_costs)
m_costs[vect_body] = adjust_body_cost (loop_vinfo, scalar_costs,
m_costs[vect_body]);
+ /* Apply the heuristic described above m_stp_sequence_cost. Prefer
+ the scalar code in the event of a tie, since there is more chance
+ of scalar code being optimized with surrounding operations. */
+ if (!loop_vinfo
+ && scalar_costs
+ && m_stp_sequence_cost != ~0U
+ && m_stp_sequence_cost >= scalar_costs->m_stp_sequence_cost)
+ m_costs[vect_body] = 2 * scalar_costs->total_cost ();
+
vector_costs::finish_cost (scalar_costs);
}
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 3c72bda..5909184 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4405,6 +4405,33 @@
}
)
+;; Implement MAX/MIN (A, B) - C using SUBS/ADDS followed by CSEL/CSINV/CSINC.
+;; See aarch64_maxmin_plus_const for details about the supported cases.
+(define_insn_and_split "*aarch64_minmax_plus"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (plus:GPI
+ (MAXMIN:GPI
+ (match_operand:GPI 1 "register_operand" "r")
+ (match_operand:GPI 2 "const_int_operand"))
+ (match_operand:GPI 3 "aarch64_plus_immediate")))
+ (clobber (reg:CC CC_REGNUM))]
+ "aarch64_maxmin_plus_const (<CODE>, operands, false)"
+ "#"
+ "&& 1"
+ [(parallel
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_dup 1) (match_dup 4)))
+ (set (match_dup 6)
+ (plus:GPI (match_dup 1) (match_dup 3)))])
+ (set (match_dup 0)
+ (if_then_else:GPI (match_dup 5) (match_dup 6) (match_dup 7)))]
+ {
+ if (!aarch64_maxmin_plus_const (<CODE>, operands, true))
+ gcc_unreachable ();
+ }
+ [(set_attr "length" "8")]
+)
+
;; -------------------------------------------------------------------
;; Logical operations
;; -------------------------------------------------------------------
@@ -4531,7 +4558,7 @@
(define_split
[(set (match_operand:GPI 0 "register_operand")
- (LOGICAL:GPI
+ (LOGICAL_OR_PLUS:GPI
(and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand")
(match_operand:QI 2 "aarch64_shift_imm_<mode>"))
(match_operand:GPI 3 "const_int_operand"))
@@ -4544,16 +4571,23 @@
&& REGNO (operands[1]) == REGNO (operands[4])))
&& (trunc_int_for_mode (GET_MODE_MASK (GET_MODE (operands[4]))
<< INTVAL (operands[2]), <MODE>mode)
- == INTVAL (operands[3]))"
+ == INTVAL (operands[3]))
+ && (<CODE> != PLUS
+ || (GET_MODE_MASK (GET_MODE (operands[4]))
+ & INTVAL (operands[3])) == 0)"
[(set (match_dup 5) (zero_extend:GPI (match_dup 4)))
- (set (match_dup 0) (LOGICAL:GPI (ashift:GPI (match_dup 5) (match_dup 2))
- (match_dup 5)))]
- "operands[5] = gen_reg_rtx (<MODE>mode);"
+ (set (match_dup 0) (match_dup 6))]
+ {
+ operands[5] = gen_reg_rtx (<MODE>mode);
+ rtx shift = gen_rtx_ASHIFT (<MODE>mode, operands[5], operands[2]);
+ rtx_code new_code = (<CODE> == PLUS ? IOR : <CODE>);
+ operands[6] = gen_rtx_fmt_ee (new_code, <MODE>mode, shift, operands[5]);
+ }
)
(define_split
[(set (match_operand:GPI 0 "register_operand")
- (LOGICAL:GPI
+ (LOGICAL_OR_PLUS:GPI
(and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand")
(match_operand:QI 2 "aarch64_shift_imm_<mode>"))
(match_operand:GPI 4 "const_int_operand"))
@@ -4562,11 +4596,17 @@
&& pow2_or_zerop (UINTVAL (operands[3]) + 1)
&& (trunc_int_for_mode (UINTVAL (operands[3])
<< INTVAL (operands[2]), <MODE>mode)
- == INTVAL (operands[4]))"
+ == INTVAL (operands[4]))
+ && (<CODE> != PLUS
+ || (INTVAL (operands[4]) & INTVAL (operands[3])) == 0)"
[(set (match_dup 5) (and:GPI (match_dup 1) (match_dup 3)))
- (set (match_dup 0) (LOGICAL:GPI (ashift:GPI (match_dup 5) (match_dup 2))
- (match_dup 5)))]
- "operands[5] = gen_reg_rtx (<MODE>mode);"
+ (set (match_dup 0) (match_dup 6))]
+ {
+ operands[5] = gen_reg_rtx (<MODE>mode);
+ rtx shift = gen_rtx_ASHIFT (<MODE>mode, operands[5], operands[2]);
+ rtx_code new_code = (<CODE> == PLUS ? IOR : <CODE>);
+ operands[6] = gen_rtx_fmt_ee (new_code, <MODE>mode, shift, operands[5]);
+ }
)
(define_split
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 88067a3..e72fdf35 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -2122,6 +2122,9 @@
;; Code iterator for logical operations
(define_code_iterator LOGICAL [and ior xor])
+;; LOGICAL with plus, for when | gets converted to +.
+(define_code_iterator LOGICAL_OR_PLUS [and ior xor plus])
+
;; LOGICAL without AND.
(define_code_iterator LOGICAL_OR [ior xor])
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index 74819c6..402f025 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -4460,7 +4460,7 @@ gcn_expand_reduc_scalar (machine_mode mode, rtx src, int unspec)
pair of lanes, then on every pair of results from the previous
iteration (thereby effectively reducing every 4 lanes) and so on until
all lanes are reduced. */
- rtx in, out = src;
+ rtx in, out = force_reg (mode, src);
for (int i = 0, shift = 1; i < 6; i++, shift <<= 1)
{
rtx shift_val = gen_rtx_CONST_INT (VOIDmode, shift);
diff --git a/gcc/config/i386/host-cygwin.cc b/gcc/config/i386/host-cygwin.cc
index fcf6333..05ad3a8 100644
--- a/gcc/config/i386/host-cygwin.cc
+++ b/gcc/config/i386/host-cygwin.cc
@@ -51,18 +51,18 @@ static void *
cygwin_gt_pch_get_address (size_t sz, int fd)
{
void *base;
- off_t p = lseek(fd, 0, SEEK_CUR);
+ off_t p = lseek (fd, 0, SEEK_CUR);
if (p == (off_t) -1)
- fatal_error (input_location, "can%'t get position in PCH file: %m");
+ fatal_error (input_location, "cannot get position in PCH file: %m");
/* Cygwin requires that the underlying file be at least
as large as the requested mapping. */
if ((size_t) p < sz)
- {
- if ( ftruncate (fd, sz) == -1 )
- fatal_error (input_location, "can%'t extend PCH file: %m");
- }
+ {
+ if (ftruncate (fd, sz) == -1)
+ fatal_error (input_location, "cannot extend PCH file: %m");
+ }
base = mmap (NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
@@ -71,8 +71,8 @@ cygwin_gt_pch_get_address (size_t sz, int fd)
else
munmap (base, sz);
- if (lseek (fd, p, SEEK_SET) == (off_t) -1 )
- fatal_error (input_location, "can%'t set position in PCH file: %m");
+ if (lseek (fd, p, SEEK_SET) == (off_t) -1)
+ fatal_error (input_location, "cannot set position in PCH file: %m");
return base;
}
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index bc3ef072..e76c017 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -11018,6 +11018,12 @@ init_float128_ibm (machine_mode mode)
set_conv_libfunc (trunc_optab, DDmode, mode, "__dpd_trunctfdd");
set_conv_libfunc (sext_optab, TDmode, mode, "__dpd_extendtftd");
+ set_conv_libfunc (sfix_optab, DImode, mode, "__fixtfdi");
+ set_conv_libfunc (ufix_optab, DImode, mode, "__fixunstfdi");
+
+ set_conv_libfunc (sfloat_optab, mode, DImode, "__floatditf");
+ set_conv_libfunc (ufloat_optab, mode, DImode, "__floatunditf");
+
if (TARGET_POWERPC64)
{
set_conv_libfunc (sfix_optab, TImode, mode, "__fixtfti");
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1db66a7..90d4a79 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,19 @@
+2022-02-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/104107
+ PR c++/95036
+ * pt.cc (coerce_template_template_parms): Take full parms.
+ Avoid adding too much of outer_args.
+ (coerce_template_template_parm): Adjust.
+ (template_template_parm_bindings_ok_p): Adjust.
+ (convert_template_argument): Adjust.
+
+2022-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/104513
+ * constexpr.cc (potential_constant_expression_1) <case GOTO_EXPR>:
+ Don't punt if returns (target).
+
2022-02-11 Jakub Jelinek <jakub@redhat.com>
PR c++/104472
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 87f3a7b..4716694 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9065,6 +9065,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case BIND_EXPR:
return RECUR (BIND_EXPR_BODY (t), want_rval);
+ case NON_DEPENDENT_EXPR:
+ /* Treat NON_DEPENDENT_EXPR as non-constant: it's not handled by
+ constexpr evaluation or tsubst, so fold_non_dependent_expr can't
+ do anything useful with it. And we shouldn't see it in a context
+ where a constant expression is strictly required, hence the assert. */
+ gcc_checking_assert (!(flags & tf_error));
+ return false;
+
case CLEANUP_POINT_EXPR:
case MUST_NOT_THROW_EXPR:
case TRY_CATCH_EXPR:
@@ -9072,7 +9080,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case EH_SPEC_BLOCK:
case EXPR_STMT:
case PAREN_EXPR:
- case NON_DEPENDENT_EXPR:
/* For convenience. */
case LOOP_EXPR:
case EXIT_EXPR:
@@ -9363,8 +9370,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case GOTO_EXPR:
{
tree *target = &TREE_OPERAND (t, 0);
- /* Gotos representing break and continue are OK. */
- if (breaks (target) || continues (target))
+ /* Gotos representing break, continue and cdtor return are OK. */
+ if (breaks (target) || continues (target) || returns (target))
{
*jump_target = *target;
return true;
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1b18e2a..6dda660 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -7731,8 +7731,8 @@ coerce_template_template_parm (tree parm,
template <template <template <class> class> class TT>
class C; */
{
- tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
- tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+ tree parmparm = DECL_TEMPLATE_PARMS (parm);
+ tree argparm = DECL_TEMPLATE_PARMS (arg);
if (!coerce_template_template_parms
(parmparm, argparm, complain, in_decl, outer_args))
@@ -8001,8 +8001,8 @@ unify_bound_ttp_args (tree tparms, tree targs, tree parm, tree& arg,
the parameters to A, and OUTER_ARGS contains A. */
static int
-coerce_template_template_parms (tree parm_parms,
- tree arg_parms,
+coerce_template_template_parms (tree parm_parms_full,
+ tree arg_parms_full,
tsubst_flags_t complain,
tree in_decl,
tree outer_args)
@@ -8011,6 +8011,9 @@ coerce_template_template_parms (tree parm_parms,
tree parm, arg;
int variadic_p = 0;
+ tree parm_parms = INNERMOST_TEMPLATE_PARMS (parm_parms_full);
+ tree arg_parms = INNERMOST_TEMPLATE_PARMS (arg_parms_full);
+
gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
@@ -8046,8 +8049,26 @@ coerce_template_template_parms (tree parm_parms,
specialized as P, so they match.*/
processing_template_decl_sentinel ptds (/*reset*/false);
++processing_template_decl;
+
tree pargs = template_parms_level_to_args (parm_parms);
- pargs = add_outermost_template_args (outer_args, pargs);
+
+ /* PARM, and thus the context in which we are passing ARG to it, may be
+ at a deeper level than ARG; when trying to coerce to ARG_PARMS, we
+ want to provide the right number of levels, so we reduce the number of
+ levels in OUTER_ARGS before prepending them. This is most important
+ when ARG is a namespace-scope template, as in alias-decl-ttp2.C.
+
+ ARG might also be deeper than PARM (ttp23). In that case, we include
+ all of OUTER_ARGS. The missing levels seem potentially problematic,
+ but I can't come up with a testcase that breaks. */
+ if (int arg_outer_levs = TMPL_PARMS_DEPTH (arg_parms_full) - 1)
+ {
+ auto x = make_temp_override (TREE_VEC_LENGTH (outer_args));
+ if (TMPL_ARGS_DEPTH (outer_args) > arg_outer_levs)
+ TREE_VEC_LENGTH (outer_args) = arg_outer_levs;
+ pargs = add_to_template_args (outer_args, pargs);
+ }
+
pargs = coerce_template_parms (arg_parms, pargs, NULL_TREE, tf_none,
/*require_all*/true, /*use_default*/true);
if (pargs != error_mark_node)
@@ -8186,16 +8207,16 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
/* Extract the template parameters from the template
argument. */
if (TREE_CODE (targ) == TEMPLATE_DECL)
- targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (targ);
+ targ_parms = DECL_TEMPLATE_PARMS (targ);
else if (TREE_CODE (targ) == TEMPLATE_TEMPLATE_PARM)
- targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_NAME (targ));
+ targ_parms = DECL_TEMPLATE_PARMS (TYPE_NAME (targ));
/* Verify that we can coerce the template template
parameters from the template argument to the template
parameter. This requires an exact match. */
if (targ_parms
&& !coerce_template_template_parms
- (DECL_INNERMOST_TEMPLATE_PARMS (tparm),
+ (DECL_TEMPLATE_PARMS (tparm),
targ_parms,
tf_none,
tparm,
@@ -8489,13 +8510,13 @@ convert_template_argument (tree parm,
val = orig_arg;
else
{
- tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+ tree parmparm = DECL_TEMPLATE_PARMS (parm);
tree argparm;
/* Strip alias templates that are equivalent to another
template. */
arg = get_underlying_template (arg);
- argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+ argparm = DECL_TEMPLATE_PARMS (arg);
if (coerce_template_template_parms (parmparm, argparm,
complain, in_decl,
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 44a0db64..73b4766 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -543,7 +543,7 @@ d_build_builtins_module (Module *m)
flag_unsafe_math_optimizations.
- Built-ins never use the GC or raise a D exception, and so are always
marked as `nothrow' and `@nogc'. */
- tf->purity = DECL_PURE_P (decl) ? PURE::strong
+ tf->purity = DECL_PURE_P (decl) ? PURE::const_
: TREE_READONLY (decl) ? PURE::const_
: DECL_IS_NOVOPS (decl) ? PURE::weak
: !DECL_ASSEMBLER_NAME_SET_P (decl) ? PURE::weak
diff --git a/gcc/d/d-gimplify.cc b/gcc/d/d-gimplify.cc
index fbeb607..a98089b7 100644
--- a/gcc/d/d-gimplify.cc
+++ b/gcc/d/d-gimplify.cc
@@ -62,6 +62,18 @@ empty_modify_p (tree type, tree op)
return empty_aggregate_p (type);
}
+/* Return TRUE if EXPR is a COMPONENT_REF to a bit-field declaration. */
+
+static bool
+bit_field_ref (const_tree expr)
+{
+ if (TREE_CODE (expr) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
+ return true;
+
+ return false;
+}
+
/* Gimplify assignment from an INIT_EXPR or MODIFY_EXPR. */
static gimplify_status
@@ -96,6 +108,13 @@ d_gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
return GS_OK;
}
+ /* Same as above, but for bit-field assignments. */
+ if (bit_field_ref (op0) && TREE_TYPE (op0) != TREE_TYPE (op1))
+ {
+ TREE_OPERAND (*expr_p, 1) = convert (TREE_TYPE (op0), op1);
+ return GS_OK;
+ }
+
return GS_UNHANDLED;
}
@@ -178,6 +197,54 @@ d_gimplify_unsigned_rshift_expr (tree *expr_p)
return GS_OK;
}
+/* Gimplify an unary expression node. */
+
+static gimplify_status
+d_gimplify_unary_expr (tree *expr_p)
+{
+ tree op0 = TREE_OPERAND (*expr_p, 0);
+
+ if (error_operand_p (op0))
+ return GS_UNHANDLED;
+
+ /* Front end doesn't know that bit-field types are really different
+ from basic types, add an explicit conversion in unary expressions. */
+ if (bit_field_ref (op0) && TREE_TYPE (op0) != TREE_TYPE (*expr_p))
+ {
+ TREE_OPERAND (*expr_p, 0) = convert (TREE_TYPE (*expr_p), op0);
+ return GS_OK;
+ }
+
+ return GS_UNHANDLED;
+}
+
+/* Gimplify a binary expression node. */
+
+static gimplify_status
+d_gimplify_binary_expr (tree *expr_p)
+{
+ tree op0 = TREE_OPERAND (*expr_p, 0);
+ tree op1 = TREE_OPERAND (*expr_p, 1);
+
+ if (error_operand_p (op0) || error_operand_p (op1))
+ return GS_UNHANDLED;
+
+ /* Front end doesn't know that bit-field types are really different
+ from basic types, add an explicit conversion in binary expressions. */
+ if (bit_field_ref (op0) || bit_field_ref (op1))
+ {
+ if (TREE_TYPE (op0) != TREE_TYPE (*expr_p))
+ TREE_OPERAND (*expr_p, 0) = convert (TREE_TYPE (*expr_p), op0);
+
+ if (TREE_TYPE (op1) != TREE_TYPE (*expr_p))
+ TREE_OPERAND (*expr_p, 1) = convert (TREE_TYPE (*expr_p), op1);
+
+ return GS_OK;
+ }
+
+ return GS_UNHANDLED;
+}
+
/* Implements the lang_hooks.gimplify_expr routine for language D.
Do gimplification of D specific expression trees in EXPR_P. */
@@ -203,6 +270,10 @@ d_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
gcc_unreachable ();
default:
+ if (UNARY_CLASS_P (*expr_p) && !CONVERT_EXPR_P (*expr_p))
+ return d_gimplify_unary_expr (expr_p);
+ if (BINARY_CLASS_P (*expr_p))
+ return d_gimplify_binary_expr (expr_p);
break;
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index 87cb48f6..02f7b74 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -161,6 +161,8 @@ Target::_init (const Param &)
this->c.longsize = int_size_in_bytes (long_integer_type_node);
this->c.long_doublesize = int_size_in_bytes (long_double_type_node);
this->c.wchar_tsize = (WCHAR_TYPE_SIZE / BITS_PER_UNIT);
+ this->c.bitFieldStyle = targetm.ms_bitfield_layout_p (unknown_type_node)
+ ? TargetC::BitFieldStyle::MS : TargetC::BitFieldStyle::Gcc_Clang;
/* Set-up target C++ ABI. */
this->cpp.reverseOverloads = false;
@@ -379,32 +381,21 @@ TargetCPP::typeMangle (Type *type)
ARG to an extern(C++) function. */
Type *
-TargetCPP::parameterType (Parameter *arg)
+TargetCPP::parameterType (Type *type)
{
- Type *t = arg->type->merge2 ();
- if (arg->storageClass & (STCout | STCref))
- t = t->referenceTo ();
- else if (arg->storageClass & STClazy)
- {
- /* Mangle as delegate. */
- TypeFunction *tf = TypeFunction::create (NULL, t, VARARGnone, LINK::d);
- TypeDelegate *td = TypeDelegate::create (tf);
- t = td->merge2 ();
- }
-
/* Could be a va_list, which we mangle as a pointer. */
Type *tvalist = target.va_listType (Loc (), NULL);
- if (t->ty == TY::Tsarray && tvalist->ty == TY::Tsarray)
+ if (type->ty == TY::Tsarray && tvalist->ty == TY::Tsarray)
{
- Type *tb = t->toBasetype ()->mutableOf ();
+ Type *tb = type->toBasetype ()->mutableOf ();
if (tb == tvalist)
{
- tb = t->nextOf ()->pointerTo ();
- t = tb->castMod (t->mod);
+ tb = type->nextOf ()->pointerTo ();
+ type = tb->castMod (type->mod);
}
}
- return t;
+ return type;
}
/* Checks whether TYPE is a vendor-specific fundamental type. Stores the result
@@ -579,6 +570,14 @@ Target::libraryObjectMonitors (FuncDeclaration *, Statement *)
return true;
}
+/* Returns true if the target supports `pragma(linkerDirective)'. */
+
+bool
+Target::supportsLinkerDirective (void) const
+{
+ return false;
+}
+
/* Decides whether an `in' parameter of the specified POD type PARAM_TYPE is to
be passed by reference or by valie. This is used only when compiling with
`-fpreview=in' enabled. */
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 5915706..91cdc9f 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-001bfd97b0e75423970260dac54f453be9b57f4c
+52844d4b1e9d6714bfd2e535f25a72074a046209
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/README.md b/gcc/d/dmd/README.md
index 6b91e22..f613ab2 100644
--- a/gcc/d/dmd/README.md
+++ b/gcc/d/dmd/README.md
@@ -33,6 +33,7 @@ Note that these groups have no strict meaning, the category assignments are a bi
|-----------------------------------------------------------------------------|-----------------------------------------------------------------------|
| [mars.d](https://github.com/dlang/dmd/blob/master/src/dmd/mars.d) | The entry point. Contains `main`. |
| [cli.d](https://github.com/dlang/dmd/blob/master/src/dmd/cli.d) | Define the command line interface |
+| [dmdparams.d](https://github.com/dlang/dmd/blob/master/src/dmd/dmdparams.d) | DMD-specific parameters |
| [globals.d](https://github.com/dlang/dmd/blob/master/src/dmd/globals.d) | Define a structure storing command line options |
| [dinifile.d](https://github.com/dlang/dmd/blob/master/src/dmd/dinifile.d) | Parse settings from .ini file (`sc.ini` / `dmd.conf`) |
| [vsoptions.d](https://github.com/dlang/dmd/blob/master/src/dmd/vsoptions.d) | Detect the Microsoft Visual Studio toolchain for linking |
diff --git a/gcc/d/dmd/access.d b/gcc/d/dmd/access.d
index 51ef049..59c77adf 100644
--- a/gcc/d/dmd/access.d
+++ b/gcc/d/dmd/access.d
@@ -51,15 +51,7 @@ bool checkAccess(AggregateDeclaration ad, Loc loc, Scope* sc, Dsymbol smember)
if (!symbolIsVisible(sc, smember))
{
- // when in @safe code or with -preview=dip1000
- if (sc.flags & SCOPE.onlysafeaccess)
- {
- // if there is a func. ask for it's opinion of safety, and if it considers the access @safe accept it.
- if (sc.func && !sc.func.setUnsafe())
- return false;
- }
-
- ad.error(loc, "%s `%s` is not accessible%s", smember.kind(), smember.toChars(), (sc.flags & SCOPE.onlysafeaccess) ? " from `@safe` code".ptr : "".ptr);
+ ad.error(loc, "%s `%s` is not accessible", smember.kind(), smember.toChars());
//printf("smember = %s %s, vis = %d, semanticRun = %d\n",
// smember.kind(), smember.toPrettyChars(), smember.visible() smember.semanticRun);
return true;
diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d
index 3e86cfa..ea10c4e 100644
--- a/gcc/d/dmd/astenums.d
+++ b/gcc/d/dmd/astenums.d
@@ -134,6 +134,8 @@ enum STC : ulong // transfer changes to declaration.h
}
+alias StorageClass = ulong;
+
/********
* Determine if it's the ambigous case of where `return` attaches to.
* Params:
@@ -302,8 +304,7 @@ enum PURE : ubyte
impure = 0, // not pure at all
fwdref = 1, // it's pure, but not known which level yet
weak = 2, // no mutable globals are read or written
- const_ = 3, // parameters are values or const
- strong = 4, // parameters are values or immutable
+ const_ = 3, // parameters are values or const = strongly pure
}
// Whether alias this dependency is recursive or not
@@ -389,3 +390,43 @@ enum InitKind : ubyte
C_,
}
+/// A linkage attribute as defined by `extern(XXX)`
+///
+/// https://dlang.org/spec/attribute.html#linkage
+enum LINK : ubyte
+{
+ default_,
+ d,
+ c,
+ cpp,
+ windows,
+ objc,
+ system,
+}
+
+/// Whether to mangle an external aggregate as a struct or class, as set by `extern(C++, struct)`
+enum CPPMANGLE : ubyte
+{
+ def, /// default
+ asStruct, /// `extern(C++, struct)`
+ asClass, /// `extern(C++, class)`
+}
+
+/// Function match levels
+///
+/// https://dlang.org/spec/function.html#function-overloading
+enum MATCH : int
+{
+ nomatch, /// no match
+ convert, /// match with conversions
+ constant, /// match with conversion to const
+ exact, /// exact match
+}
+
+/// Inline setting as defined by `pragma(inline, XXX)`
+enum PINLINE : ubyte
+{
+ default_, /// as specified on the command line
+ never, /// never inline
+ always, /// always inline
+}
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 5d44760..cf9e9ce 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -43,6 +43,7 @@ import dmd.identifier;
import dmd.mtype;
import dmd.objc; // for objc.addSymbols
import dmd.common.outbuffer;
+import dmd.root.array; // for each
import dmd.target; // for target.systemLinkage
import dmd.tokens;
import dmd.visitor;
@@ -1519,3 +1520,60 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
}
}
}
+
+/**
+ * Returns `true` if the given symbol is a symbol declared in
+ * `core.attribute` and has the given identifier.
+ *
+ * This is used to determine if a symbol is a UDA declared in
+ * `core.attribute`.
+ *
+ * Params:
+ * sym = the symbol to check
+ * ident = the name of the expected UDA
+ */
+bool isCoreUda(Dsymbol sym, Identifier ident)
+{
+ if (sym.ident != ident || !sym.parent)
+ return false;
+
+ auto _module = sym.parent.isModule();
+ return _module && _module.isCoreModule(Id.attribute);
+}
+
+/**
+ * Iterates the UDAs attached to the given symbol.
+ *
+ * If `dg` returns `!= 0`, it will stop the iteration and return that
+ * value, otherwise it will return 0.
+ *
+ * Params:
+ * sym = the symbol to get the UDAs from
+ * sc = scope to use for semantic analysis of UDAs
+ * dg = called once for each UDA. If `dg` returns `!= 0`, it will stop the
+ * iteration and return that value, otherwise it will return `0`.
+ */
+int foreachUda(Dsymbol sym, Scope* sc, int delegate(Expression) dg)
+{
+ if (!sym.userAttribDecl)
+ return 0;
+
+ auto udas = sym.userAttribDecl.getAttributes();
+ arrayExpressionSemantic(udas, sc, true);
+
+ return udas.each!((uda) {
+ if (!uda.isTupleExp())
+ return 0;
+
+ auto exps = uda.isTupleExp().exps;
+
+ return exps.each!((e) {
+ assert(e);
+
+ if (auto result = dg(e))
+ return result;
+
+ return 0;
+ });
+ });
+}
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index c4a9577..5132a2d 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -110,8 +110,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
}
if (s.exp.type && s.exp.type.toBasetype().isTypeNoreturn())
result = BE.halt;
- if (canThrow(s.exp, func, mustNotThrow))
- result |= BE.throw_;
+
+ result |= canThrow(s.exp, func, mustNotThrow);
}
}
@@ -149,7 +149,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
else if (!func.getModule().isCFile)
{
const(char)* gototype = s.isCaseStatement() ? "case" : "default";
- s.deprecation("switch case fallthrough - use 'goto %s;' if intended", gototype);
+ s.error("switch case fallthrough - use 'goto %s;' if intended", gototype);
}
}
}
@@ -214,8 +214,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
result = BE.fallthru;
if (result & BE.fallthru)
{
- if (canThrow(s.condition, func, mustNotThrow))
- result |= BE.throw_;
+ result |= canThrow(s.condition, func, mustNotThrow);
+
if (!(result & BE.break_) && s.condition.toBool().hasValue(true))
result &= ~BE.fallthru;
}
@@ -233,8 +233,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
}
if (s.condition)
{
- if (canThrow(s.condition, func, mustNotThrow))
- result |= BE.throw_;
+ result |= canThrow(s.condition, func, mustNotThrow);
+
const opt = s.condition.toBool();
if (opt.hasValue(true))
result &= ~BE.fallthru;
@@ -250,15 +250,15 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
result |= BE.fallthru;
result |= r & ~(BE.fallthru | BE.break_ | BE.continue_);
}
- if (s.increment && canThrow(s.increment, func, mustNotThrow))
- result |= BE.throw_;
+ if (s.increment)
+ result |= canThrow(s.increment, func, mustNotThrow);
}
override void visit(ForeachStatement s)
{
result = BE.fallthru;
- if (canThrow(s.aggr, func, mustNotThrow))
- result |= BE.throw_;
+ result |= canThrow(s.aggr, func, mustNotThrow);
+
if (s._body)
result |= blockExit(s._body, func, mustNotThrow) & ~(BE.break_ | BE.continue_);
}
@@ -273,8 +273,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
//printf("IfStatement::blockExit(%p)\n", s);
result = BE.none;
- if (canThrow(s.condition, func, mustNotThrow))
- result |= BE.throw_;
+ result |= canThrow(s.condition, func, mustNotThrow);
const opt = s.condition.toBool();
if (opt.hasValue(true))
@@ -313,8 +312,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
override void visit(SwitchStatement s)
{
result = BE.none;
- if (canThrow(s.condition, func, mustNotThrow))
- result |= BE.throw_;
+ result |= canThrow(s.condition, func, mustNotThrow);
+
if (s._body)
{
result |= blockExit(s._body, func, mustNotThrow);
@@ -357,8 +356,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
override void visit(ReturnStatement s)
{
result = BE.return_;
- if (s.exp && canThrow(s.exp, func, mustNotThrow))
- result |= BE.throw_;
+ if (s.exp)
+ result |= canThrow(s.exp, func, mustNotThrow);
}
override void visit(BreakStatement s)
@@ -380,8 +379,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
override void visit(WithStatement s)
{
result = BE.none;
- if (canThrow(s.exp, func, mustNotThrow))
- result = BE.throw_;
+ result |= canThrow(s.exp, func, mustNotThrow);
result |= blockExit(s._body, func, mustNotThrow);
}
@@ -483,19 +481,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
return;
}
- Type t = s.exp.type.toBasetype();
- ClassDeclaration cd = t.isClassHandle();
- assert(cd);
-
- if (cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null))
- {
- result = BE.errthrow;
- return;
- }
- if (mustNotThrow)
- s.error("`%s` is thrown but not caught", s.exp.type.toChars());
-
- result = BE.throw_;
+ result = checkThrow(s.loc, s.exp, mustNotThrow);
}
override void visit(GotoStatement s)
@@ -537,3 +523,32 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
s.accept(be);
return be.result;
}
+
+/++
+ + Checks whether `throw <exp>` throws an `Exception` or an `Error`
+ + and raises an error if this violates `nothrow`.
+ +
+ + Params:
+ + loc = location of the `throw`
+ + exp = expression yielding the throwable
+ + mustNotThrow = inside of a `nothrow` scope?
+ +
+ + Returns: `BE.[err]throw` depending on the type of `exp`
+ +/
+BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow)
+{
+ import dmd.errors : error;
+
+ Type t = exp.type.toBasetype();
+ ClassDeclaration cd = t.isClassHandle();
+ assert(cd);
+
+ if (cd == ClassDeclaration.errorException || ClassDeclaration.errorException.isBaseOf(cd, null))
+ {
+ return BE.errthrow;
+ }
+ if (mustNotThrow)
+ loc.error("`%s` is thrown but not caught", exp.type.toChars());
+
+ return BE.throw_;
+}
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index e6eb0ac..faf427d 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -18,6 +18,7 @@ import dmd.apply;
import dmd.arraytypes;
import dmd.attrib;
import dmd.astenums;
+import dmd.blockexit : BE, checkThrow;
import dmd.declaration;
import dmd.dsymbol;
import dmd.expression;
@@ -29,11 +30,28 @@ import dmd.root.rootobject;
import dmd.tokens;
import dmd.visitor;
+/**
+ * Status indicating what kind of throwable might be caused by an expression.
+ *
+ * This is a subset of `BE` restricted to the values actually used by `canThrow`.
+ */
+enum CT : BE
+{
+ /// Never throws an `Exception` or `Throwable`
+ none = BE.none,
+
+ /// Might throw an `Exception`
+ exception = BE.throw_,
+
+ // Might throw an `Error`
+ error = BE.errthrow,
+}
+
/********************************************
* Returns true if the expression may throw exceptions.
* If 'mustNotThrow' is true, generate an error if it throws
*/
-extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow)
+extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustNotThrow)
{
//printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());
// stop walking if we determine this expression can throw
@@ -42,6 +60,7 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
alias visit = typeof(super).visit;
FuncDeclaration func;
bool mustNotThrow;
+ CT result;
public:
extern (D) this(FuncDeclaration func, bool mustNotThrow)
@@ -62,7 +81,7 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
e.checkOverridenDtor(null, f, dd => dd.type.toTypeFunction().isnothrow, "not nothrow");
}
- stop = true; // if any function throws, then the whole expression throws
+ result |= CT.exception;
}
}
@@ -72,7 +91,7 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
override void visit(DeclarationExp de)
{
- stop = Dsymbol_canThrow(de.declaration, func, mustNotThrow);
+ result |= Dsymbol_canThrow(de.declaration, func, mustNotThrow);
}
override void visit(CallExp ce)
@@ -83,18 +102,27 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
if (global.errors && !ce.e1.type)
return; // error recovery
- import dmd.id : Id;
-
- if (ce.f && ce.f.ident == Id._d_delstruct)
+ if (ce.f && ce.arguments.dim > 0)
{
- // Only check if the dtor throws.
Type tb = (*ce.arguments)[0].type.toBasetype();
- auto ts = tb.nextOf().baseElemOf().isTypeStruct();
- if (ts)
+ auto tbNext = tb.nextOf();
+ if (tbNext)
{
- auto sd = ts.sym;
- if (sd.dtor)
- checkFuncThrows(ce, sd.dtor);
+ auto ts = tbNext.baseElemOf().isTypeStruct();
+ if (ts)
+ {
+ import dmd.id : Id;
+
+ auto sd = ts.sym;
+ if (sd.dtor && ce.f.ident == Id._d_delstruct)
+ checkFuncThrows(ce, sd.dtor);
+ else if (sd.postblit &&
+ (ce.f.ident == Id._d_arrayctor || ce.f.ident == Id._d_arraysetctor))
+ {
+ checkFuncThrows(ce, sd.postblit);
+ return;
+ }
+ }
}
}
@@ -124,7 +152,7 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
e1 = pe.e1;
ce.error("`%s` is not `nothrow`", e1.toChars());
}
- stop = true;
+ result |= CT.exception;
}
override void visit(NewExp ne)
@@ -187,6 +215,13 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
checkFuncThrows(ae, postblit);
}
+ override void visit(ThrowExp te)
+ {
+ const res = checkThrow(te.loc, te.e1, mustNotThrow);
+ assert((res & ~(CT.exception | CT.error)) == 0);
+ result |= res;
+ }
+
override void visit(NewAnonClassExp)
{
assert(0); // should have been lowered by semantic()
@@ -194,18 +229,22 @@ extern (C++) bool canThrow(Expression e, FuncDeclaration func, bool mustNotThrow
}
scope CanThrow ct = new CanThrow(func, mustNotThrow);
- return walkPostorder(e, ct);
+ walkPostorder(e, ct);
+ return ct.result;
}
/**************************************
* Does symbol, when initialized, throw?
* Mirrors logic in Dsymbol_toElem().
*/
-private bool Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow)
+private CT Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow)
{
+ CT result;
+
int symbolDg(Dsymbol s)
{
- return Dsymbol_canThrow(s, func, mustNotThrow);
+ result |= Dsymbol_canThrow(s, func, mustNotThrow);
+ return 0;
}
//printf("Dsymbol_toElem() %s\n", s.toChars());
@@ -225,20 +264,19 @@ private bool Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow
if (vd._init)
{
if (auto ie = vd._init.isExpInitializer())
- if (canThrow(ie.exp, func, mustNotThrow))
- return true;
+ result |= canThrow(ie.exp, func, mustNotThrow);
}
if (vd.needsScopeDtor())
- return canThrow(vd.edtor, func, mustNotThrow);
+ result |= canThrow(vd.edtor, func, mustNotThrow);
}
}
else if (auto ad = s.isAttribDeclaration())
{
- return ad.include(null).foreachDsymbol(&symbolDg) != 0;
+ ad.include(null).foreachDsymbol(&symbolDg);
}
else if (auto tm = s.isTemplateMixin())
{
- return tm.members.foreachDsymbol(&symbolDg) != 0;
+ tm.members.foreachDsymbol(&symbolDg);
}
else if (auto td = s.isTupleDeclaration())
{
@@ -250,11 +288,10 @@ private bool Dsymbol_canThrow(Dsymbol s, FuncDeclaration func, bool mustNotThrow
Expression eo = cast(Expression)o;
if (auto se = eo.isDsymbolExp())
{
- if (Dsymbol_canThrow(se.s, func, mustNotThrow))
- return true;
+ result |= Dsymbol_canThrow(se.s, func, mustNotThrow);
}
}
}
}
- return false;
+ return result;
}
diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d
index 76e1d7f..16f7b2f 100644
--- a/gcc/d/dmd/constfold.d
+++ b/gcc/d/dmd/constfold.d
@@ -120,18 +120,13 @@ UnionExp Not(Type type, Expression e1)
{
UnionExp ue = void;
Loc loc = e1.loc;
+ // BUG: Should be replaced with e1.toBool().get(), but this is apparently
+ // executed for some expressions that cannot be const-folded
+ // To be fixed in another PR
emplaceExp!(IntegerExp)(&ue, loc, e1.toBool().hasValue(false) ? 1 : 0, type);
return ue;
}
-private UnionExp Bool(Type type, Expression e1)
-{
- UnionExp ue = void;
- Loc loc = e1.loc;
- emplaceExp!(IntegerExp)(&ue, loc, e1.toBool().hasValue(true) ? 1 : 0, type);
- return ue;
-}
-
UnionExp Add(const ref Loc loc, Type type, Expression e1, Expression e2)
{
UnionExp ue = void;
@@ -1093,19 +1088,14 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
}
else if (tb.ty == Tbool)
{
- bool val = void;
const opt = e1.toBool();
- if (opt.hasValue(true))
- val = true;
- else if (opt.hasValue(false))
- val = false;
- else
+ if (opt.isEmpty())
{
cantExp(ue);
return ue;
}
- emplaceExp!(IntegerExp)(&ue, loc, val, type);
+ emplaceExp!(IntegerExp)(&ue, loc, opt.get(), type);
}
else if (type.isintegral())
{
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 8d3f3b3..38a78a0 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -35,7 +35,8 @@ final class CParser(AST) : Parser!AST
{
AST.Dsymbols* symbols; // symbols declared in current scope
- bool addFuncName; /// add declaration of __func__ to function symbol table
+ bool addFuncName; /// add declaration of __func__ to function symbol table
+ bool importBuiltins; /// seen use of C compiler builtins, so import __builtins;
extern (D) this(TARGET)(AST.Module _module, const(char)[] input, bool doDocComment,
const ref TARGET target)
@@ -72,7 +73,6 @@ final class CParser(AST) : Parser!AST
{
//printf("cparseTranslationUnit()\n");
symbols = new AST.Dsymbols();
- addBuiltinDeclarations();
while (1)
{
if (token.value == TOK.endOfFile)
@@ -82,6 +82,15 @@ final class CParser(AST) : Parser!AST
auto ld = new AST.LinkDeclaration(token.loc, LINK.c, symbols);
wrap.push(ld);
+ if (importBuiltins)
+ {
+ /* Seen references to C builtin functions.
+ * Import their definitions
+ */
+ auto s = new AST.Import(Loc.initial, null, Id.builtins, null, false);
+ wrap.push(s);
+ }
+
return wrap;
}
@@ -596,6 +605,7 @@ final class CParser(AST) : Parser!AST
* string-literal
* ( expression )
* generic-selection
+ * __builtin_va_arg(assign_expression, type)
*/
AST.Expression cparsePrimaryExp()
{
@@ -606,9 +616,20 @@ final class CParser(AST) : Parser!AST
switch (token.value)
{
case TOK.identifier:
- if (token.ident is Id.__func__)
+ const id = token.ident.toString();
+ if (id.length > 2 && id[0] == '_' && id[1] == '_') // leading double underscore
{
- addFuncName = true; // implicitly declare __func__
+ if (token.ident is Id.__func__)
+ {
+ addFuncName = true; // implicitly declare __func__
+ }
+ else if (token.ident is Id.builtin_va_arg)
+ {
+ e = cparseBuiltin_va_arg();
+ break;
+ }
+ else
+ importBuiltins = true; // probably one of those compiler extensions
}
e = new AST.IdentifierExp(loc, token.ident);
nextToken();
@@ -1449,6 +1470,40 @@ final class CParser(AST) : Parser!AST
return cparseAssignExp();
}
+ /*****************************
+ * gcc extension:
+ * type __builtin_va_arg(assign-expression, type)
+ * Rewrite as `va_arg` template from `core.stdc.stdarg`:
+ * va_arg!(type)(assign-expression);
+ * Lexer is on `__builtin_va_arg`
+ */
+ private AST.Expression cparseBuiltin_va_arg()
+ {
+ importBuiltins = true; // need core.stdc.stdarg
+
+ nextToken();
+ check(TOK.leftParenthesis);
+
+ auto arguments = new AST.Expressions();
+ auto arg = cparseAssignExp();
+ arguments.push(arg);
+
+ check(TOK.comma);
+
+ auto t = cparseTypeName();
+ auto tiargs = new AST.Objects();
+ tiargs.push(t);
+
+ const loc = loc;
+ auto ti = new AST.TemplateInstance(loc, Id.va_arg, tiargs);
+ auto tie = new AST.ScopeExp(loc, ti);
+
+ AST.Expression e = new AST.CallExp(loc, tie, arguments);
+
+ check(TOK.rightParenthesis);
+ return e;
+ }
+
//}
/********************************************************************************/
/********************************* Declaration Parser ***************************/
@@ -1481,6 +1536,14 @@ final class CParser(AST) : Parser!AST
return;
}
+ if (token.value == TOK._import) // import declaration extension
+ {
+ auto a = parseImport();
+ if (a && a.length)
+ symbols.append(a);
+ return;
+ }
+
auto symbolsSave = symbols;
Specifier specifier;
specifier.packalign = this.packalign;
@@ -1504,7 +1567,7 @@ final class CParser(AST) : Parser!AST
*/
auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) :
(tt.tok == TOK.union_) ? new AST.UnionDeclaration(tt.loc, tt.id) :
- new AST.EnumDeclaration(tt.loc, tt.id, AST.Type.tint32);
+ new AST.EnumDeclaration(tt.loc, tt.id, tt.base);
stag.members = tt.members;
if (!symbols)
symbols = new AST.Dsymbols();
@@ -1550,26 +1613,18 @@ final class CParser(AST) : Parser!AST
case TOK.semicolon:
case TOK.asm_:
case TOK.__attribute__:
- /* This is a data definition, there cannot now be a
- * function definition.
- */
- first = false;
if (token.value == TOK.asm_)
asmname = cparseSimpleAsmExpr();
if (token.value == TOK.__attribute__)
{
cparseGnuAttributes(specifier);
if (token.value == TOK.leftCurly)
- {
- error("attributes should be specified before the function definition");
- auto t = &token;
- if (skipBraces(t))
- {
- token = *t;
- return;
- }
- }
+ break; // function definition
}
+ /* This is a data definition, there cannot now be a
+ * function definition.
+ */
+ first = false;
break;
default:
@@ -1636,6 +1691,30 @@ final class CParser(AST) : Parser!AST
isalias = false;
}
}
+ else if (auto tt = dt.isTypeTag())
+ {
+ if (tt.id || tt.tok == TOK.enum_)
+ {
+ /* `struct tag;` and `struct tag { ... };`
+ * always result in a declaration in the current scope
+ */
+ auto stag = (tt.tok == TOK.struct_) ? new AST.StructDeclaration(tt.loc, tt.id, false) :
+ (tt.tok == TOK.union_) ? new AST.UnionDeclaration(tt.loc, tt.id) :
+ new AST.EnumDeclaration(tt.loc, tt.id, tt.base);
+ stag.members = tt.members;
+ tt.members = null;
+ if (!symbols)
+ symbols = new AST.Dsymbols();
+ symbols.push(stag);
+ if (tt.tok == TOK.enum_)
+ {
+ if (!tt.members)
+ error(tt.loc, "`enum %s` has no members", stag.toChars());
+ isalias = false;
+ s = new AST.AliasDeclaration(token.loc, id, stag);
+ }
+ }
+ }
if (isalias)
s = new AST.AliasDeclaration(token.loc, id, dt);
}
@@ -1768,6 +1847,7 @@ final class CParser(AST) : Parser!AST
if (pl.varargs != AST.VarArg.none && pl.length)
error("function identifier-list cannot end with `...`");
ft.parameterList.varargs = AST.VarArg.variadic; // but C11 allows extra arguments
+ importBuiltins = true; // will need __va_list_tag
auto plLength = pl.length;
if (symbols.length != plLength)
error("%d identifiers does not match %d declarations", cast(int)plLength, cast(int)symbols.length);
@@ -2230,8 +2310,14 @@ final class CParser(AST) : Parser!AST
case TKW.xcomplex | TKW.xdouble: t = AST.Type.tcomplex64; break;
case TKW.xcomplex | TKW.xlong | TKW.xdouble: t = realType(RTFlags.complex); break;
- case TKW.xident: t = new AST.TypeIdentifier(loc, previd);
+ case TKW.xident:
+ {
+ const idx = previd.toString();
+ if (idx.length > 2 && idx[0] == '_' && idx[1] == '_') // leading double underscore
+ importBuiltins = true; // probably one of those compiler extensions
+ t = new AST.TypeIdentifier(loc, previd);
break;
+ }
case TKW.xtag:
break; // t is already set
@@ -2599,6 +2685,7 @@ final class CParser(AST) : Parser!AST
if (token.value == TOK.rightParenthesis) // func()
{
nextToken();
+ importBuiltins = true; // will need __va_list_tag
return AST.ParameterList(parameters, AST.VarArg.variadic, varargsStc);
}
@@ -2613,6 +2700,7 @@ final class CParser(AST) : Parser!AST
{
if (parameters.length == 0) // func(...)
error("named parameter required before `...`");
+ importBuiltins = true; // will need __va_list_tag
varargs = AST.VarArg.variadic; // C-style variadics
nextToken();
check(TOK.rightParenthesis);
@@ -3011,6 +3099,17 @@ final class CParser(AST) : Parser!AST
nextToken();
}
+ /* clang extension: add optional base type after the identifier
+ * https://en.cppreference.com/w/cpp/language/enum
+ * enum Identifier : Type
+ */
+ AST.Type base = AST.Type.tint32; // C11 6.7.2.2-4 implementation defined default base type
+ if (token.value == TOK.colon)
+ {
+ nextToken();
+ base = cparseTypeName();
+ }
+
AST.Dsymbols* members;
if (token.value == TOK.leftCurly)
{
@@ -3084,7 +3183,7 @@ final class CParser(AST) : Parser!AST
* redeclaration, or reference to existing declaration.
* Defer to the semantic() pass with a TypeTag.
*/
- return new AST.TypeTag(loc, TOK.enum_, tag, members);
+ return new AST.TypeTag(loc, TOK.enum_, tag, base, members);
}
/*************************************
@@ -3124,17 +3223,14 @@ final class CParser(AST) : Parser!AST
if (token.value == TOK.leftCurly)
{
nextToken();
- auto symbolsSave = symbols;
- symbols = new AST.Dsymbols();
+ members = new AST.Dsymbols(); // so `members` will be non-null even with 0 members
while (token.value != TOK.rightCurly)
{
- cparseStructDeclaration();
+ cparseStructDeclaration(members);
if (token.value == TOK.endOfFile)
break;
}
- members = symbols; // `members` will be non-null even with 0 members
- symbols = symbolsSave;
check(TOK.rightCurly);
if ((*members).length == 0) // C11 6.7.2.1-8
@@ -3152,7 +3248,7 @@ final class CParser(AST) : Parser!AST
* redeclaration, or reference to existing declaration.
* Defer to the semantic() pass with a TypeTag.
*/
- return new AST.TypeTag(loc, structOrUnion, tag, members);
+ return new AST.TypeTag(loc, structOrUnion, tag, null, members);
}
/*************************************
@@ -3169,18 +3265,19 @@ final class CParser(AST) : Parser!AST
* struct-declarator:
* declarator
* declarator (opt) : constant-expression
+ * Params:
+ * members = where to put the fields (members)
*/
- void cparseStructDeclaration()
+ void cparseStructDeclaration(AST.Dsymbols* members)
{
//printf("cparseStructDeclaration()\n");
if (token.value == TOK._Static_assert)
{
auto s = cparseStaticAssert();
- symbols.push(s);
+ members.push(s);
return;
}
- auto symbolsSave = symbols;
Specifier specifier;
specifier.packalign = this.packalign;
auto tspec = cparseSpecifierQualifierList(LVL.member, specifier);
@@ -3209,10 +3306,8 @@ final class CParser(AST) : Parser!AST
* the containing struct
*/
auto ad = new AST.AnonDeclaration(tt.loc, tt.tok == TOK.union_, tt.members);
- if (!symbols)
- symbols = new AST.Dsymbols();
auto s = applySpecifier(ad, specifier);
- symbols.push(s);
+ members.push(s);
return;
}
if (!tt.id && !tt.members)
@@ -3270,18 +3365,14 @@ final class CParser(AST) : Parser!AST
if (token.value == TOK.__attribute__)
cparseGnuAttributes(specifier);
- AST.Dsymbol s = null;
- symbols = symbolsSave;
- if (!symbols)
- symbols = new AST.Dsymbols; // lazilly create it
-
if (!tspec && !specifier.scw && !specifier.mod)
error("specifier-qualifier-list required");
else if (width)
{
if (specifier.alignExps)
error("no alignment-specifier for bit field declaration"); // C11 6.7.5-2
- s = new AST.BitFieldDeclaration(width.loc, dt, id, width);
+ auto s = new AST.BitFieldDeclaration(width.loc, dt, id, width);
+ members.push(s);
}
else if (id)
{
@@ -3291,11 +3382,10 @@ final class CParser(AST) : Parser!AST
// declare the symbol
// Give member variables an implicit void initializer
auto initializer = new AST.VoidInitializer(token.loc);
- s = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(LVL.member, specifier));
+ AST.Dsymbol s = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(LVL.member, specifier));
s = applySpecifier(s, specifier);
+ members.push(s);
}
- if (s !is null)
- symbols.push(s);
switch (token.value)
{
@@ -4391,39 +4481,5 @@ final class CParser(AST) : Parser!AST
return s;
}
- /***********************************
- * Add global target-dependent builtin declarations.
- */
- private void addBuiltinDeclarations()
- {
- void genBuiltinFunc(Identifier id, AST.VarArg va)
- {
- auto tva_list = new AST.TypeIdentifier(Loc.initial, Id.builtin_va_list);
- auto parameters = new AST.Parameters();
- parameters.push(new AST.Parameter(STC.parameter | STC.ref_, tva_list, null, null, null));
- auto pl = AST.ParameterList(parameters, va, 0);
- auto tf = new AST.TypeFunction(pl, AST.Type.tvoid, LINK.c, 0);
- auto s = new AST.FuncDeclaration(Loc.initial, Loc.initial, id, AST.STC.static_, tf, false);
- symbols.push(s);
- }
-
- /* void __builtin_va_start(__builtin_va_list, ...);
- * The second argument is supposed to be of any type, so fake it with the ...
- */
- genBuiltinFunc(Id.builtin_va_start, AST.VarArg.variadic);
-
- /* void __builtin_va_end(__builtin_va_list);
- */
- genBuiltinFunc(Id.builtin_va_end, AST.VarArg.none);
-
- /* struct __va_list_tag
- * {
- * uint, uint, void*, void*
- * }
- */
- auto s = new AST.StructDeclaration(Loc.initial, Id.va_list_tag, false);
- symbols.push(s);
- }
-
//}
}
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 7cb2092..986b53f 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -1315,7 +1315,18 @@ private final class CppMangleVisitor : Visitor
foreach (n, fparam; parameterList)
{
- Type t = target.cpp.parameterType(fparam);
+ Type t = fparam.type.merge2();
+ if (fparam.isReference())
+ t = t.referenceTo();
+ else if (fparam.storageClass & STC.lazy_)
+ {
+ // Mangle as delegate
+ auto tf = new TypeFunction(ParameterList(), t, LINK.d);
+ auto td = new TypeDelegate(tf);
+ t = td.merge();
+ }
+ else if (Type cpptype = target.cpp.parameterType(t))
+ t = cpptype;
if (t.ty == Tsarray)
{
// Static arrays in D are passed by value; no counterpart in C++
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 4a80d17..91b3861 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -858,11 +858,8 @@ MATCH implicitConvTo(Expression e, Type t)
* convert to immutable
*/
if (e.f &&
- (global.params.useDIP1000 != FeatureState.enabled || // lots of legacy code breaks with the following purity check
- e.f.isPure() >= PURE.strong ||
- // Special case exemption for Object.dup() which we assume is implemented correctly
- e.f.ident == Id.dup &&
- e.f.toParent2() == ClassDeclaration.object.toParent()) &&
+ // lots of legacy code breaks with the following purity check
+ (global.params.useDIP1000 != FeatureState.enabled || e.f.isPure() >= PURE.const_) &&
e.f.isReturnIsolated() // check isReturnIsolated last, because it is potentially expensive.
)
{
@@ -2245,9 +2242,12 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
ex = ex.castTo(sc, totuple ? (*totuple.arguments)[i].type : t);
(*te.exps)[i] = ex;
}
+ if (totuple)
+ te.type = totuple;
result = te;
- /* Questionable behavior: In here, result.type is not set to t.
+ /* Questionable behavior: In here, result.type is not set to t
+ * if target type is not a tuple of same length.
* Therefoe:
* TypeTuple!(int, int) values;
* auto values2 = cast(long)values;
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index 1fb4779..ce463c0 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -446,6 +446,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
*poffset = 0;
while (cd)
{
+ assert(cd.baseClass || cd.semanticRun >= PASS.semanticdone || cd.isInterfaceDeclaration());
if (this == cd.baseClass)
return true;
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index aa143d4..494b60f 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -1048,7 +1048,6 @@ extern (C++) class VarDeclaration : Declaration
uint endlinnum; // line number of end of scope that this var lives in
uint offset;
uint sequenceNumber; // order the variables are declared
- __gshared uint nextSequenceNumber; // the counter for sequenceNumber
structalign_t alignment;
// When interpreting, these point to the value (NULL if value not determinable)
@@ -1099,7 +1098,6 @@ extern (C++) class VarDeclaration : Declaration
this._init = _init;
ctfeAdrOnStack = AdrOnStackNone;
this.storage_class = storage_class;
- sequenceNumber = ++nextSequenceNumber;
}
static VarDeclaration create(const ref Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_)
@@ -1657,12 +1655,10 @@ extern (C++) class VarDeclaration : Declaration
// Sequence numbers work when there are no special VarDeclaration's involved
if (!((this.storage_class | v.storage_class) & special))
{
- // FIXME: VarDeclaration's for parameters are created in semantic3, so
- // they will have a greater sequence number than local variables.
- // Hence reverse the result for mixed comparisons.
- const exp = this.isParameter() == v.isParameter();
+ assert(this.sequenceNumber != this.sequenceNumber.init);
+ assert(v.sequenceNumber != v.sequenceNumber.init);
- return (this.sequenceNumber < v.sequenceNumber) == exp;
+ return (this.sequenceNumber < v.sequenceNumber);
}
// Assume that semantic produces temporaries according to their lifetime
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index dd6dd41..90e48f8 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -16,6 +16,7 @@ module dmd.denum;
import core.stdc.stdio;
+import dmd.astenums;
import dmd.attrib;
import dmd.gluelayer;
import dmd.declaration;
@@ -60,7 +61,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
extern (D) this(const ref Loc loc, Identifier ident, Type memtype)
{
super(loc, ident);
- //printf("EnumDeclaration() %s\n", toChars());
+ //printf("EnumDeclaration() %p %s : %s\n", this, toChars(), memtype.toChars());
type = new TypeEnum(this);
this.memtype = memtype;
visibility = Visibility(Visibility.Kind.undefined);
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index fb8ed9b..b55b981 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -99,7 +99,15 @@ public Expression ctfeInterpret(Expression e)
Expression result = interpret(e, null);
- result = copyRegionExp(result);
+ // Report an error if the expression contained a `ThrowException` and
+ // hence generated an uncaught exception
+ if (auto tee = result.isThrownExceptionExp())
+ {
+ tee.generateUncaughtError();
+ result = CTFEExp.cantexp;
+ }
+ else
+ result = copyRegionExp(result);
if (!CTFEExp.isCantExp(result))
result = scrubReturnValue(e.loc, result);
@@ -1601,14 +1609,20 @@ public:
istate.start = null;
}
- incUsageCtfe(istate, s.loc);
+ interpretThrow(s.exp, s.loc);
+ }
+
+ /// Interpret `throw <exp>` found at the specified location `loc`
+ private void interpretThrow(Expression exp, const ref Loc loc)
+ {
+ incUsageCtfe(istate, loc);
- Expression e = interpretRegion(s.exp, istate);
+ Expression e = interpretRegion(exp, istate);
if (exceptionOrCant(e))
return;
assert(e.op == EXP.classReference);
- result = ctfeEmplaceExp!ThrownExceptionExp(s.loc, e.isClassReferenceExp());
+ result = ctfeEmplaceExp!ThrownExceptionExp(loc, e.isClassReferenceExp());
}
override void visit(ScopeGuardStatement s)
@@ -6149,6 +6163,15 @@ public:
return;
}
+ override void visit(ThrowExp te)
+ {
+ debug (LOG)
+ {
+ printf("%s ThrowExpression::interpret()\n", e.loc.toChars());
+ }
+ interpretThrow(te.e1, te.loc);
+ }
+
override void visit(PtrExp e)
{
debug (LOG)
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index 07ebc27..2a3777b 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -59,7 +59,6 @@ enum SCOPE
compile = 0x0100, /// inside __traits(compile)
ignoresymbolvisibility = 0x0200, /// ignore symbol visibility
/// https://issues.dlang.org/show_bug.cgi?id=15907
- onlysafeaccess = 0x0400, /// unsafe access is not allowed for @safe code
Cfile = 0x0800, /// C semantics apply
free = 0x8000, /// is on free list
@@ -74,7 +73,7 @@ enum SCOPE
/// Flags that are carried along with a scope push()
private enum PersistentFlags =
SCOPE.contract | SCOPE.debug_ | SCOPE.ctfe | SCOPE.compile | SCOPE.constraint |
- SCOPE.noaccesscheck | SCOPE.onlysafeaccess | SCOPE.ignoresymbolvisibility |
+ SCOPE.noaccesscheck | SCOPE.ignoresymbolvisibility |
SCOPE.printf | SCOPE.scanf | SCOPE.Cfile;
struct Scope
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index c4b3380..7823351 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -2345,7 +2345,7 @@ extern (C++) final class DsymbolTable : RootObject
Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds)
{
enum log = false;
- if (log) printf("handleTagSymbols('%s')\n", s.toChars());
+ if (log) printf("handleTagSymbols('%s') add %p existing %p\n", s.toChars(), s, s2);
auto sd = s.isScopeDsymbol(); // new declaration
auto sd2 = s2.isScopeDsymbol(); // existing declaration
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 387dfe3..1cb167a 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -356,6 +356,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (sc && sc.inunion && sc.inunion.isAnonDeclaration())
dsym.overlapped = true;
+ dsym.sequenceNumber = global.varSequenceNumber++;
+
Scope* scx = null;
if (dsym._scope)
{
@@ -1636,7 +1638,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// Should be merged with PragmaStatement
//printf("\tPragmaDeclaration::semantic '%s'\n", pd.toChars());
- if (target.mscoff)
+ if (target.supportsLinkerDirective())
{
if (pd.ident == Id.linkerDirective)
{
@@ -2177,7 +2179,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
/* C11 6.7.2.2
*/
- ed.memtype = Type.tint32; // C11 6.7.2.2-4 implementation defined
+ assert(ed.memtype);
int nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0
void emSemantic(EnumMember em, ref int nextValue)
@@ -3457,9 +3459,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
}
- /* These quirky conditions mimic what VC++ appears to do
+ /* These quirky conditions mimic what happens when virtual
+ inheritance is implemented by producing a virtual base table
+ with offsets to each of the virtual bases.
*/
- if (target.mscoff && cd.classKind == ClassKind.cpp &&
+ if (target.cpp.splitVBasetable && cd.classKind == ClassKind.cpp &&
cd.baseClass && cd.baseClass.vtbl.dim)
{
/* if overriding an interface function, then this is not
@@ -3557,7 +3561,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
goto Lintro;
}
- if (fdv.isDeprecated)
+ if (fdv.isDeprecated && !funcdecl.isDeprecated)
deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
funcdecl.toPrettyChars, fdv.toPrettyChars);
@@ -3646,11 +3650,17 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
funcdecl.tintro = fdv.tintro;
else if (!funcdecl.type.equals(fdv.type))
{
+ auto tnext = funcdecl.type.nextOf();
+ if (auto handle = tnext.isClassHandle())
+ {
+ if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete())
+ handle.dsymbolSemantic(null);
+ }
/* Only need to have a tintro if the vptr
* offsets differ
*/
int offset;
- if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
+ if (fdv.type.nextOf().isBaseOf(tnext, &offset))
{
funcdecl.tintro = fdv.type;
}
@@ -3812,7 +3822,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
deprecation(funcdecl.loc,
"`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
funcdecl.toPrettyChars);
- if (funcdecl.isDeprecated)
+
+ if (funcdecl.isDeprecated && !(funcdecl.foverrides.length && funcdecl.foverrides[0].isDeprecated))
deprecation(funcdecl.loc,
"`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
funcdecl.toPrettyChars);
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index c0d17f7..9fe8472 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -6223,114 +6223,62 @@ extern (C++) class TemplateInstance : ScopeDsymbol
*/
final bool needsCodegen()
{
- if (!minst)
- {
- // If this is a speculative instantiation,
- // 1. do codegen if ancestors really needs codegen.
- // 2. become non-speculative if siblings are not speculative
-
- TemplateInstance tnext = this.tnext;
- TemplateInstance tinst = this.tinst;
- // At first, disconnect chain first to prevent infinite recursion.
- this.tnext = null;
- this.tinst = null;
+ // minst is finalized after the 1st invocation.
+ // tnext and tinst are only needed for the 1st invocation and
+ // cleared for further invocations.
+ TemplateInstance tnext = this.tnext;
+ TemplateInstance tinst = this.tinst;
+ this.tnext = null;
+ this.tinst = null;
- // Determine necessity of tinst before tnext.
- if (tinst && tinst.needsCodegen())
- {
- minst = tinst.minst; // cache result
- if (global.params.allInst && minst)
- {
- return true;
- }
- assert(minst);
- assert(minst.isRoot() || minst.rootImports());
- return true;
- }
- if (tnext && (tnext.needsCodegen() || tnext.minst))
- {
- minst = tnext.minst; // cache result
- if (global.params.allInst && minst)
- {
- return true;
- }
- assert(minst);
- return minst.isRoot() || minst.rootImports();
- }
-
- // Elide codegen because this is really speculative.
- return false;
- }
-
- if (global.params.allInst)
- {
- return true;
- }
-
- if (isDiscardable())
+ if (errors || (inst && inst.isDiscardable()))
{
+ minst = null; // mark as speculative
return false;
}
- /* Even when this is reached to the codegen pass,
- * a non-root nested template should not generate code,
- * due to avoid ODR violation.
- */
- if (enclosing && enclosing.inNonRoot())
+ if (global.params.allInst)
{
- if (tinst)
- {
- auto r = tinst.needsCodegen();
- minst = tinst.minst; // cache result
- return r;
- }
- if (tnext)
- {
- auto r = tnext.needsCodegen();
- minst = tnext.minst; // cache result
- return r;
- }
- return false;
- }
+ // Do codegen if there is an instantiation from a root module, to maximize link-ability.
- if (global.params.useUnitTests)
- {
- // Prefer instantiations from root modules, to maximize link-ability.
- if (minst.isRoot())
+ // Do codegen if `this` is instantiated from a root module.
+ if (minst && minst.isRoot())
return true;
- TemplateInstance tnext = this.tnext;
- TemplateInstance tinst = this.tinst;
- this.tnext = null;
- this.tinst = null;
-
+ // Do codegen if the ancestor needs it.
if (tinst && tinst.needsCodegen())
{
minst = tinst.minst; // cache result
assert(minst);
- assert(minst.isRoot() || minst.rootImports());
+ assert(minst.isRoot());
return true;
}
- if (tnext && tnext.needsCodegen())
+
+ // Do codegen if a sibling needs it.
+ if (tnext)
{
- minst = tnext.minst; // cache result
- assert(minst);
- assert(minst.isRoot() || minst.rootImports());
- return true;
+ if (tnext.needsCodegen())
+ {
+ minst = tnext.minst; // cache result
+ assert(minst);
+ assert(minst.isRoot());
+ return true;
+ }
+ else if (!minst && tnext.minst)
+ {
+ minst = tnext.minst; // cache result from non-speculative sibling
+ return false;
+ }
}
- // https://issues.dlang.org/show_bug.cgi?id=2500 case
- if (minst.rootImports())
- return true;
-
- // Elide codegen because this is not included in root instances.
+ // Elide codegen because there's no instantiation from any root modules.
return false;
}
else
{
- // Prefer instantiations from non-root module, to minimize object code size.
+ // Prefer instantiations from non-root modules, to minimize object code size.
- /* If a TemplateInstance is ever instantiated by non-root modules,
+ /* If a TemplateInstance is ever instantiated from a non-root module,
* we do not have to generate code for it,
* because it will be generated when the non-root module is compiled.
*
@@ -6341,22 +6289,51 @@ extern (C++) class TemplateInstance : ScopeDsymbol
* or the compilation of B do the actual instantiation?
*
* See https://issues.dlang.org/show_bug.cgi?id=2500.
+ *
+ * => Elide codegen if there is at least one instantiation from a non-root module
+ * which doesn't import any root modules.
*/
- if (!minst.isRoot() && !minst.rootImports())
- return false;
- TemplateInstance tnext = this.tnext;
- this.tnext = null;
-
- if (tnext && !tnext.needsCodegen() && tnext.minst)
+ // If the ancestor isn't speculative,
+ // 1. do codegen if the ancestor needs it
+ // 2. elide codegen if the ancestor doesn't need it (non-root instantiation of ancestor incl. subtree)
+ if (tinst)
{
- minst = tnext.minst; // cache result
- assert(!minst.isRoot());
+ const needsCodegen = tinst.needsCodegen(); // sets tinst.minst
+ if (tinst.minst) // not speculative
+ {
+ minst = tinst.minst; // cache result
+ return needsCodegen;
+ }
+ }
+
+ // Elide codegen if `this` doesn't need it.
+ if (minst && !minst.isRoot() && !minst.rootImports())
return false;
+
+ // Elide codegen if a (non-speculative) sibling doesn't need it.
+ if (tnext)
+ {
+ const needsCodegen = tnext.needsCodegen(); // sets tnext.minst
+ if (tnext.minst) // not speculative
+ {
+ if (!needsCodegen)
+ {
+ minst = tnext.minst; // cache result
+ assert(!minst.isRoot() && !minst.rootImports());
+ return false;
+ }
+ else if (!minst)
+ {
+ minst = tnext.minst; // cache result from non-speculative sibling
+ return true;
+ }
+ }
}
- // Do codegen because this is not included in non-root instances.
- return true;
+ // Unless `this` is still speculative (=> all further siblings speculative too),
+ // do codegen because we found no guaranteed-codegen'd non-root instantiation.
+ return minst !is null;
}
}
@@ -7311,7 +7288,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if ((td && td.literal) || (ti && ti.enclosing) || (d && !d.isDataseg() && !(d.storage_class & STC.manifest) && (!d.isFuncDeclaration() || d.isFuncDeclaration().isNested()) && !isTemplateMixin()))
{
Dsymbol dparent = sa.toParent2();
- if (!dparent)
+ if (!dparent || dparent.isModule)
goto L1;
else if (!enclosing)
enclosing = dparent;
@@ -7370,13 +7347,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
Module mi = minst; // instantiated . inserted module
- if (global.params.useUnitTests)
- {
- // Turn all non-root instances to speculative
- if (mi && !mi.isRoot())
- mi = null;
- }
-
//printf("%s.appendToModuleMember() enclosing = %s mi = %s\n",
// toPrettyChars(),
// enclosing ? enclosing.toPrettyChars() : null,
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index dbc21b3..5871ada 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -16,6 +16,7 @@ import core.stdc.string;
import core.stdc.ctype;
import dmd.astcodegen;
+import dmd.astenums;
import dmd.arraytypes;
import dmd.attrib;
import dmd.dsymbol;
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index e60ee9c..d2a9060 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -691,11 +691,8 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag)
}
// If va's lifetime encloses v's, then error
- if (va &&
- (va.enclosesLifetimeOf(v) && !(v.storage_class & (STC.parameter | STC.temp)) ||
- // va is class reference
- ae.e1.isDotVarExp() && va.type.toBasetype().isTypeClass() && (va.enclosesLifetimeOf(v) ||
- !va.isScope()) ||
+ if (va && !va.isDataseg() &&
+ (va.enclosesLifetimeOf(v) && !(v.storage_class & STC.temp) ||
vaIsRef ||
va.isReference() && !(v.storage_class & (STC.parameter | STC.temp))) &&
fd.setUnsafe())
@@ -768,7 +765,6 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag)
}
}
-ByRef:
foreach (VarDeclaration v; er.byref)
{
if (log) printf("byref: %s\n", v.toChars());
@@ -797,8 +793,7 @@ ByRef:
// If va's lifetime encloses v's, then error
if (va &&
- (va.enclosesLifetimeOf(v) && !(v.isParameter() && v.isRef()) ||
- va.isDataseg()) &&
+ (va.enclosesLifetimeOf(v) || (va.isRef() && !(va.storage_class & STC.temp)) || va.isDataseg()) &&
fd.setUnsafe())
{
if (!gag)
@@ -807,26 +802,6 @@ ByRef:
continue;
}
- if (va && v.isReference())
- {
- Dsymbol pva = va.toParent2();
- for (Dsymbol pv = p; pv; )
- {
- pv = pv.toParent2();
- if (pva == pv) // if v is nested inside pva
- {
- if (fd.setUnsafe())
- {
- if (!gag)
- error(ae.loc, "reference `%s` assigned to `%s` with longer lifetime", v.toChars(), va.toChars());
- result = true;
- continue ByRef;
- }
- break;
- }
- }
- }
-
if (!(va && va.isScope()))
notMaybeScope(v);
@@ -1323,7 +1298,9 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
msg = "returning `%s` escapes a reference to parameter `%s`";
supplemental = vsr == ScopeRef.Ref_ReturnScope
? "perhaps remove `scope` parameter annotation so `return` applies to `ref`"
- : "perhaps annotate the parameter with `return`";
+ : v.ident is Id.This
+ ? "perhaps annotate the function with `return`"
+ : "perhaps annotate the parameter with `return`";
}
else
{
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 523015e..4258e9b 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -25,7 +25,6 @@ import dmd.arraytypes;
import dmd.astenums;
import dmd.ast_node;
import dmd.gluelayer;
-import dmd.canthrow;
import dmd.constfold;
import dmd.ctfeexpr;
import dmd.ctorflow;
@@ -466,7 +465,17 @@ private Expression callCpCtor(Scope* sc, Expression e, Type destinationType)
*/
auto tmp = copyToTemp(STC.rvalue, "__copytmp", e);
if (sd.hasCopyCtor && destinationType)
- tmp.type = destinationType;
+ {
+ // https://issues.dlang.org/show_bug.cgi?id=22619
+ // If the destination type is inout we can preserve it
+ // only if inside an inout function; if we are not inside
+ // an inout function, then we will preserve the type of
+ // the source
+ if (destinationType.hasWild && !(sc.func.storage_class & STC.wild))
+ tmp.type = e.type;
+ else
+ tmp.type = destinationType;
+ }
tmp.storage_class |= STC.nodtor;
tmp.dsymbolSemantic(sc);
Expression de = new DeclarationExp(e.loc, tmp);
@@ -4681,6 +4690,31 @@ extern (C++) final class AssertExp : UnaExp
}
/***********************************************************
+ * `throw <e1>` as proposed by DIP 1034.
+ *
+ * Replacement for the deprecated `ThrowStatement` that can be nested
+ * in other expression.
+ */
+extern (C++) final class ThrowExp : UnaExp
+{
+ extern (D) this(const ref Loc loc, Expression e)
+ {
+ super(loc, EXP.throw_, __traits(classInstanceSize, ThrowExp), e);
+ this.type = Type.tnoreturn;
+ }
+
+ override ThrowExp syntaxCopy()
+ {
+ return new ThrowExp(loc, e1.syntaxCopy());
+ }
+
+ override void accept(Visitor v)
+ {
+ v.visit(this);
+ }
+}
+
+/***********************************************************
*/
extern (C++) final class DotIdExp : UnaExp
{
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index f848cce..18ef90a 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -48,7 +48,9 @@ struct Symbol; // back end symbol
void expandTuples(Expressions *exps);
bool isTrivialExp(Expression *e);
bool hasSideEffect(Expression *e, bool assumeImpureCalls = false);
-bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
+
+enum BE : int32_t;
+BE canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
typedef unsigned char OwnedBy;
enum
@@ -742,6 +744,14 @@ public:
void accept(Visitor *v) { v->visit(this); }
};
+class ThrowExp : public UnaExp
+{
+public:
+ ThrowExp *syntaxCopy();
+
+ void accept(Visitor *v) { v->visit(this); }
+};
+
class DotIdExp : public UnaExp
{
public:
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 1008606..6eda688 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -3604,16 +3604,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (!cdthis)
{
+ if (!sc.hasThis)
+ {
+ string msg = "cannot construct " ~
+ (cd.isAnonymous ? "anonymous nested class" : "nested class `%s`") ~
+ " because no implicit `this` reference to outer class" ~
+ (cdn.isAnonymous ? "" : " `%s`") ~ " is available\0";
+
+ exp.error(msg.ptr, cd.toChars, cdn.toChars);
+ return setError();
+ }
+
// Supply an implicit 'this' and try again
exp.thisexp = new ThisExp(exp.loc);
for (Dsymbol sp = sc.parent; 1; sp = sp.toParentLocal())
{
- if (!sp)
- {
- exp.error("outer class `%s` `this` needed to `new` nested class `%s`",
- cdn.toChars(), cd.toChars());
- return setError();
- }
ClassDeclaration cdp = sp.isClassDeclaration();
if (!cdp)
continue;
@@ -5702,12 +5707,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|| global.params.useDeprecated != DiagnosticReporting.error;
const bool preventAliasThis = e.targ.hasDeprecatedAliasThis && !deprecationAllowed;
- // baseClass might not be set if either targ or tspec is forward referenced.
- if (auto tc = e.targ.isTypeClass())
- tc.sym.dsymbolSemantic(null);
- if (auto tc = e.tspec.isTypeClass())
- tc.sym.dsymbolSemantic(null);
-
if (preventAliasThis && e.targ.ty == Tstruct)
{
if ((cast(TypeStruct) e.targ).implicitConvToWithoutAliasThis(e.tspec))
@@ -6396,6 +6395,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
: Expression.combine(temporariesPrefix, exp).expressionSemantic(sc);
}
+ override void visit(ThrowExp te)
+ {
+ import dmd.statementsem;
+
+ if (StatementSemanticVisitor.throwSemantic(te.loc, te.e1, sc))
+ result = te;
+ else
+ setError();
+ }
+
override void visit(DotIdExp exp)
{
static if (LOGSEMANTIC)
@@ -6913,6 +6922,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.error("cannot take address of `%s`", exp.e1.toChars());
return setError();
}
+ if (auto dve = exp.e1.isDotVarExp())
+ {
+ /* https://issues.dlang.org/show_bug.cgi?id=22749
+ * Error about taking address of any bit-field, regardless of
+ * whether SCOPE.Cfile is set.
+ */
+ if (auto bf = dve.var.isBitFieldDeclaration())
+ {
+ exp.error("cannot take address of bit-field `%s`", bf.toChars());
+ return setError();
+ }
+ }
bool hasOverloads;
if (auto f = isFuncAddress(exp, &hasOverloads))
@@ -7511,6 +7532,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// https://issues.dlang.org/show_bug.cgi?id=19954
if (exp.e1.type.ty == Ttuple)
{
+ if (exp.to)
+ {
+ if (TypeTuple tt = exp.to.isTypeTuple())
+ {
+ if (exp.e1.type.implicitConvTo(tt))
+ {
+ result = exp.e1.castTo(sc, tt);
+ return;
+ }
+ }
+ }
TupleExp te = exp.e1.isTupleExp();
if (te.exps.dim == 1)
exp.e1 = (*te.exps)[0];
@@ -7531,7 +7563,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.to.ty == Ttuple)
{
- exp.error("cannot cast `%s` to tuple type `%s`", exp.e1.toChars(), exp.to.toChars());
+ exp.error("cannot cast `%s` of type `%s` to tuple type `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars());
return setError();
}
@@ -8016,7 +8048,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Expression el = new ArrayLengthExp(exp.loc, exp.e1);
el = el.expressionSemantic(sc);
el = el.optimize(WANTvalue);
- if (el.op == EXP.int64)
+ if (el.op == EXP.int64 && t1b.ty == Tsarray)
{
// Array length is known at compile-time. Upper is in bounds if it fits length.
dinteger_t length = el.toInteger();
@@ -9894,7 +9926,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Expression id = new IdentifierExp(exp.loc, Id.empty);
id = new DotIdExp(exp.loc, id, Id.object);
id = new DotIdExp(exp.loc, id, func);
- id = id.expressionSemantic(sc);
auto arguments = new Expressions();
arguments.push(new CastExp(ae.loc, ae.e1, ae.e1.type.nextOf.arrayOf).expressionSemantic(sc));
@@ -11355,7 +11386,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- EXP cmpop;
+
+ EXP cmpop = exp.op;
if (auto e = exp.op_overload(sc, &cmpop))
{
if (!e.type.isscalar() && e.type.equals(exp.e1.type))
@@ -11365,6 +11397,38 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (e.op == EXP.call)
{
+
+ if (t1.ty == Tclass && t2.ty == Tclass)
+ {
+ // Lower to object.__cmp(e1, e2)
+ Expression cl = new IdentifierExp(exp.loc, Id.empty);
+ cl = new DotIdExp(exp.loc, cl, Id.object);
+ cl = new DotIdExp(exp.loc, cl, Id.__cmp);
+ cl = cl.expressionSemantic(sc);
+
+ auto arguments = new Expressions();
+ // Check if op_overload found a better match by calling e2.opCmp(e1)
+ // If the operands were swapped, then the result must be reversed
+ // e1.opCmp(e2) == -e2.opCmp(e1)
+ // cmpop takes care of this
+ if (exp.op == cmpop)
+ {
+ arguments.push(exp.e1);
+ arguments.push(exp.e2);
+ }
+ else
+ {
+ // Use better match found by op_overload
+ arguments.push(exp.e2);
+ arguments.push(exp.e1);
+ }
+
+ cl = new CallExp(exp.loc, cl, arguments);
+ cl = new CmpExp(cmpop, exp.loc, cl, new IntegerExp(0));
+ result = cl.expressionSemantic(sc);
+ return;
+ }
+
e = new CmpExp(cmpop, exp.loc, e, IntegerExp.literal!0);
e = e.expressionSemantic(sc);
}
@@ -11372,6 +11436,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
+
if (Expression ex = typeCombine(exp, sc))
{
result = ex;
@@ -13213,7 +13278,16 @@ Expression getVarExp(EnumMember em, const ref Loc loc, Scope* sc)
if (em.errors)
return ErrorExp.get();
Expression e = new VarExp(loc, em);
- return e.expressionSemantic(sc);
+ e = e.expressionSemantic(sc);
+ if (!(sc.flags & SCOPE.Cfile) && em.isCsymbol())
+ {
+ /* C11 types them as int. But if in D file,
+ * type qualified names as the enum
+ */
+ e.type = em.parent.isEnumDeclaration().type;
+ assert(e.type);
+ }
+ return e;
}
@@ -13245,6 +13319,8 @@ Expression toBoolean(Expression exp, Scope* sc)
case EXP.assign:
case EXP.construct:
case EXP.blit:
+ if (sc.flags & SCOPE.Cfile)
+ return exp;
// Things like:
// if (a = b) ...
// are usually mistakes.
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index b5148be..f3aeb0f 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -3052,7 +3052,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
// all of overloads are templates
if (td)
{
- .error(loc, "%s `%s.%s` cannot deduce function from argument types `!(%s)%s`",
+ .error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
tiargsBuf.peekChars(), fargsBuf.peekChars());
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index 22ccddd..eccd1ee 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -327,6 +327,7 @@ extern (C++) struct Global
Array!Identifier* debugids; /// command line debug versions and predefined versions
bool hasMainFunction; /// Whether a main function has already been compiled in (for -main switch)
+ uint varSequenceNumber = 1; /// Relative lifetime of `VarDeclaration` within a function, used for `scope` checks
enum recursionLimit = 500; /// number of recursive template expansions before abort
@@ -614,48 +615,5 @@ nothrow:
}
}
-/// A linkage attribute as defined by `extern(XXX)`
-///
-/// https://dlang.org/spec/attribute.html#linkage
-enum LINK : ubyte
-{
- default_,
- d,
- c,
- cpp,
- windows,
- objc,
- system,
-}
-
-/// Whether to mangle an external aggregate as a struct or class, as set by `extern(C++, struct)`
-enum CPPMANGLE : ubyte
-{
- def, /// default
- asStruct, /// `extern(C++, struct)`
- asClass, /// `extern(C++, class)`
-}
-
-/// Function match levels
-///
-/// https://dlang.org/spec/function.html#function-overloading
-enum MATCH : int
-{
- nomatch, /// no match
- convert, /// match with conversions
- constant, /// match with conversion to const
- exact, /// exact match
-}
-
-/// Inline setting as defined by `pragma(inline, XXX)`
-enum PINLINE : ubyte
-{
- default_, /// as specified on the command line
- never, /// never inline
- always, /// always inline
-}
-
-alias StorageClass = ulong;
-
/// Collection of global state
extern (C++) __gshared Global global;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 4e76967..49fa5b9 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -290,6 +290,7 @@ struct Global
Array<class Identifier*>* debugids; // command line debug versions and predefined versions
bool hasMainFunction;
+ unsigned varSequenceNumber;
/* Start gagging. Return the current number of gagged errors
*/
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index 6fc86c3..43b63f1 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -2364,6 +2364,12 @@ public:
buf.writeByte(')');
}
+ override void visit(ThrowExp e)
+ {
+ buf.writestring("throw ");
+ expToBuffer(e.e1, PREC.unary, buf, hgs);
+ }
+
override void visit(DotIdExp e)
{
expToBuffer(e.e1, PREC.primary, buf, hgs);
@@ -3896,6 +3902,11 @@ private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
buf.writeByte(' ');
if (t.id)
buf.writestring(t.id.toChars());
+ if (t.base.ty != TY.Tint32)
+ {
+ buf.writestring(" : ");
+ visitWithMask(t.base, t.mod, buf, hgs);
+ }
}
void visitTuple(TypeTuple t)
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index cef1b8e..7f51e92 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -478,6 +478,7 @@ immutable Msgtable[] msgtable =
{ "hasCopyConstructor" },
{ "isCopyable" },
{ "toType" },
+ { "parameters" },
// For C++ mangling
{ "allocator" },
@@ -507,12 +508,11 @@ immutable Msgtable[] msgtable =
{ "__func__" },
{ "noreturn" },
{ "__pragma", "pragma" },
+ { "builtins", "__builtins" },
{ "builtin_va_list", "__builtin_va_list" },
- { "builtin_va_start", "__builtin_va_start" },
{ "builtin_va_arg", "__builtin_va_arg" },
- { "builtin_va_copy", "__builtin_va_copy" },
- { "builtin_va_end", "__builtin_va_end" },
{ "va_list_tag", "__va_list_tag" },
+ { "va_arg" },
{ "pack" },
{ "show" },
{ "push" },
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index ba2dd17..3183c8d 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -302,8 +302,7 @@ public:
//property(name, "impure");
break;
case PURE.weak: return property(name, "weak");
- case PURE.const_: return property(name, "const");
- case PURE.strong: return property(name, "strong");
+ case PURE.const_: return property(name, "strong");
case PURE.fwdref: return property(name, "fwdref");
}
}
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 0257faa..fefad28 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -230,6 +230,57 @@ bool isSomeChar(TY ty) pure nothrow @nogc @safe
return ty == Tchar || ty == Twchar || ty == Tdchar;
}
+/************************************
+ * Determine mutability of indirections in (ref) t.
+ *
+ * Returns: When the type has any mutable indirections, returns 0.
+ * When all indirections are immutable, returns 2.
+ * Otherwise, when the type has const/inout indirections, returns 1.
+ *
+ * Params:
+ * isref = if true, check `ref t`; otherwise, check just `t`
+ * t = the type that is being checked
+ */
+int mutabilityOfType(bool isref, Type t)
+{
+ if (isref)
+ {
+ if (t.mod & MODFlags.immutable_)
+ return 2;
+ if (t.mod & (MODFlags.const_ | MODFlags.wild))
+ return 1;
+ return 0;
+ }
+
+ t = t.baseElemOf();
+
+ if (!t.hasPointers() || t.mod & MODFlags.immutable_)
+ return 2;
+
+ /* Accept immutable(T)[] and immutable(T)* as being strongly pure
+ */
+ if (t.ty == Tarray || t.ty == Tpointer)
+ {
+ Type tn = t.nextOf().toBasetype();
+ if (tn.mod & MODFlags.immutable_)
+ return 2;
+ if (tn.mod & (MODFlags.const_ | MODFlags.wild))
+ return 1;
+ }
+
+ /* The rest of this is too strict; fix later.
+ * For example, the only pointer members of a struct may be immutable,
+ * which would maintain strong purity.
+ * (Just like for dynamic arrays and pointers above.)
+ */
+ if (t.mod & (MODFlags.const_ | MODFlags.wild))
+ return 1;
+
+ /* Should catch delegates and function pointers, and fold in their purity
+ */
+ return 0;
+}
+
/****************
* dotExp() bit flags
*/
@@ -4217,54 +4268,11 @@ extern (C++) final class TypeFunction : TypeNext
if (tf.purity != PURE.fwdref)
return;
- /* Determine purity level based on mutability of t
- * and whether it is a 'ref' type or not.
- */
- static PURE purityOfType(bool isref, Type t)
- {
- if (isref)
- {
- if (t.mod & MODFlags.immutable_)
- return PURE.strong;
- if (t.mod & (MODFlags.const_ | MODFlags.wild))
- return PURE.const_;
- return PURE.weak;
- }
-
- t = t.baseElemOf();
-
- if (!t.hasPointers() || t.mod & MODFlags.immutable_)
- return PURE.strong;
-
- /* Accept immutable(T)[] and immutable(T)* as being strongly pure
- */
- if (t.ty == Tarray || t.ty == Tpointer)
- {
- Type tn = t.nextOf().toBasetype();
- if (tn.mod & MODFlags.immutable_)
- return PURE.strong;
- if (tn.mod & (MODFlags.const_ | MODFlags.wild))
- return PURE.const_;
- }
-
- /* The rest of this is too strict; fix later.
- * For example, the only pointer members of a struct may be immutable,
- * which would maintain strong purity.
- * (Just like for dynamic arrays and pointers above.)
- */
- if (t.mod & (MODFlags.const_ | MODFlags.wild))
- return PURE.const_;
-
- /* Should catch delegates and function pointers, and fold in their purity
- */
- return PURE.weak;
- }
-
- purity = PURE.strong; // assume strong until something weakens it
+ purity = PURE.const_; // assume strong until something weakens it
/* Evaluate what kind of purity based on the modifiers for the parameters
*/
- Lloop: foreach (i, fparam; tf.parameterList)
+ foreach (i, fparam; tf.parameterList)
{
Type t = fparam.type;
if (!t)
@@ -4275,33 +4283,11 @@ extern (C++) final class TypeFunction : TypeNext
purity = PURE.weak;
break;
}
- switch (purityOfType((fparam.storageClass & STC.ref_) != 0, t))
- {
- case PURE.weak:
- purity = PURE.weak;
- break Lloop; // since PURE.weak, no need to check further
-
- case PURE.const_:
- purity = PURE.const_;
- continue;
-
- case PURE.strong:
- continue;
-
- default:
- assert(0);
- }
+ const pref = (fparam.storageClass & STC.ref_) != 0;
+ if (mutabilityOfType(pref, t) == 0)
+ purity = PURE.weak;
}
- if (purity > PURE.weak && tf.nextOf())
- {
- /* Adjust purity based on mutability of return type.
- * https://issues.dlang.org/show_bug.cgi?id=15862
- */
- const purity2 = purityOfType(tf.isref, tf.nextOf());
- if (purity2 < purity)
- purity = purity2;
- }
tf.purity = purity;
}
@@ -6306,10 +6292,7 @@ extern (C++) final class TypeClass : Type
extern (D) MATCH implicitConvToWithoutAliasThis(Type to)
{
- MATCH m = constConv(to);
- if (m > MATCH.nomatch)
- return m;
-
+ // Run semantic before checking whether class is convertible
ClassDeclaration cdto = to.isClassHandle();
if (cdto)
{
@@ -6318,11 +6301,15 @@ extern (C++) final class TypeClass : Type
cdto.dsymbolSemantic(null);
if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete())
sym.dsymbolSemantic(null);
- if (cdto.isBaseOf(sym, null) && MODimplicitConv(mod, to.mod))
- {
- //printf("'to' is base\n");
- return MATCH.convert;
- }
+ }
+ MATCH m = constConv(to);
+ if (m > MATCH.nomatch)
+ return m;
+
+ if (cdto && cdto.isBaseOf(sym, null) && MODimplicitConv(mod, to.mod))
+ {
+ //printf("'to' is base\n");
+ return MATCH.convert;
}
return MATCH.nomatch;
}
@@ -6373,6 +6360,9 @@ extern (C++) final class TypeClass : Type
override MOD deduceWild(Type t, bool isRef)
{
+ // If sym is forward referenced:
+ if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete())
+ sym.dsymbolSemantic(null);
ClassDeclaration cd = t.isClassHandle();
if (cd && (sym == cd || cd.isBaseOf(sym, null)))
return Type.deduceWild(t, isRef);
@@ -6760,19 +6750,21 @@ extern (C++) final class TypeTag : Type
Loc loc; /// location of declaration
TOK tok; /// TOK.struct_, TOK.union_, TOK.enum_
Identifier id; /// tag name identifier
+ Type base; /// base type for enums otherwise null
Dsymbols* members; /// members of struct, null if none
Type resolved; /// type after semantic() in case there are more others
/// pointing to this instance, which can happen with
/// struct S { int a; } s1, *s2;
- extern (D) this(const ref Loc loc, TOK tok, Identifier id, Dsymbols* members)
+ extern (D) this(const ref Loc loc, TOK tok, Identifier id, Type base, Dsymbols* members)
{
//printf("TypeTag %p\n", this);
super(Ttag);
this.loc = loc;
this.tok = tok;
this.id = id;
+ this.base = base;
this.members = members;
}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index fde5027..cb60236 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -553,7 +553,6 @@ enum class PURE : unsigned char
fwdref = 1, // it's pure, but not known which level yet
weak = 2, // no mutable globals are read or written
const_ = 3, // parameters are values or const
- strong = 4 // parameters are values or immutable
};
class Parameter : public ASTNode
diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d
index ed3f832..f25e779 100644
--- a/gcc/d/dmd/nogc.d
+++ b/gcc/d/dmd/nogc.d
@@ -71,6 +71,7 @@ public:
if (!e.f)
return;
+ // Treat lowered hook calls as their original expressions.
auto fd = stripHookTraceImpl(e.f);
if (fd.ident == Id._d_arraysetlengthT)
{
diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d
index 29f920a..40f2676 100644
--- a/gcc/d/dmd/nspace.d
+++ b/gcc/d/dmd/nspace.d
@@ -48,6 +48,7 @@ module dmd.nspace;
import dmd.aggregate;
import dmd.arraytypes;
+import dmd.astenums;
import dmd.dscope;
import dmd.dsymbol;
import dmd.dsymbolsem;
diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d
index 6d283e1..9e92212 100644
--- a/gcc/d/dmd/objc.d
+++ b/gcc/d/dmd/objc.d
@@ -818,64 +818,6 @@ extern(C++) private final class Supported : Objc
expression.errorSupplemental("`tupleof` is not available for members " ~
"of Objective-C classes. Please use the Objective-C runtime instead");
}
-
-extern(D) private:
-
- /**
- * Returns `true` if the given symbol is a symbol declared in
- * `core.attribute` and has the given identifier.
- *
- * This is used to determine if a symbol is a UDA declared in
- * `core.attribute`.
- *
- * Params:
- * sd = the symbol to check
- * ident = the name of the expected UDA
- */
- bool isCoreUda(ScopeDsymbol sd, Identifier ident) const
- {
- if (sd.ident != ident || !sd.parent)
- return false;
-
- auto _module = sd.parent.isModule();
- return _module && _module.isCoreModule(Id.attribute);
- }
-
- /**
- * Iterates the UDAs attached to the given function declaration.
- *
- * If `dg` returns `!= 0`, it will stop the iteration and return that
- * value, otherwise it will return 0.
- *
- * Params:
- * fd = the function declaration to get the UDAs from
- * dg = called once for each UDA. If `dg` returns `!= 0`, it will stop the
- * iteration and return that value, otherwise it will return `0`.
- */
- int foreachUda(FuncDeclaration fd, Scope* sc, int delegate(Expression) dg) const
- {
- if (!fd.userAttribDecl)
- return 0;
-
- auto udas = fd.userAttribDecl.getAttributes();
- arrayExpressionSemantic(udas, sc, true);
-
- return udas.each!((uda) {
- if (!uda.isTupleExp())
- return 0;
-
- auto exps = uda.isTupleExp().exps;
-
- return exps.each!((e) {
- assert(e);
-
- if (auto result = dg(e))
- return result;
-
- return 0;
- });
- });
- }
}
/*
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index c932d043..5d6128b 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -853,11 +853,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
{
// Rewrite (e1 op e2) as e2.opfunc(e1)
result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s);
+ // When reversing operands of comparison operators,
+ // need to reverse the sense of the op
+ if (pop)
+ *pop = reverseRelation(e.op);
}
- // When reversing operands of comparison operators,
- // need to reverse the sense of the op
- if (pop)
- *pop = reverseRelation(e.op);
return;
}
}
@@ -1052,7 +1052,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
e.e2 = new DotIdExp(e.loc, e.e2, Id._tupleof);
auto sc2 = sc.push();
- sc2.flags = (sc2.flags & ~SCOPE.onlysafeaccess) | SCOPE.noaccesscheck;
+ sc2.flags |= SCOPE.noaccesscheck;
result = e.expressionSemantic(sc2);
sc2.pop();
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index 5864fa2..5b4ebd7 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -1130,8 +1130,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
const e1Opt = e.e1.toBool();
if (e.e2.isConst())
{
- bool n1 = e1Opt.hasValue(true);
- bool n2 = e.e2.toBool().hasValue(true);
+ bool n1 = e1Opt.get();
+ bool n2 = e.e2.toBool().get();
ret = new IntegerExp(e.loc, oror ? (n1 || n2) : (n1 && n2), e.type);
}
else if (e1Opt.hasValue(!oror))
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 700f3c5..63afeb2 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -128,6 +128,7 @@ immutable PREC[EXP.max + 1] precedence =
EXP.new_ : PREC.unary,
EXP.newAnonymousClass : PREC.unary,
EXP.cast_ : PREC.unary,
+ EXP.throw_ : PREC.unary,
EXP.vector : PREC.unary,
EXP.pow : PREC.pow,
@@ -443,6 +444,13 @@ class Parser(AST) : Lexer
}
decldefs = parseDeclDefs(0, &lastDecl);
+
+ if (token.value == TOK.rightCurly)
+ {
+ error(token.loc, "unmatched closing brace");
+ goto Lerr;
+ }
+
if (token.value != TOK.endOfFile)
{
error(token.loc, "unrecognized declaration");
@@ -643,7 +651,43 @@ class Parser(AST) : Lexer
goto Lerror;
case TOK.unittest_:
- if (global.params.useUnitTests || global.params.doDocComments || global.params.doHdrGeneration)
+ /**
+ * Ignore unittests in non-root modules.
+ *
+ * This mainly means that unittests *inside templates* are only
+ * ever instantiated if the module lexically declaring the
+ * template is one of the root modules.
+ *
+ * E.g., compiling some project with `-unittest` does NOT
+ * compile and later run any unittests in instantiations of
+ * templates declared in other libraries.
+ *
+ * Declaring unittests *inside* templates is considered an anti-
+ * pattern. In almost all cases, the unittests don't depend on
+ * the template parameters, but instantiate the template with
+ * fixed arguments (e.g., Nullable!T unittests instantiating
+ * Nullable!int), so compiling and running identical tests for
+ * each template instantiation is hardly desirable.
+ * But adding a unittest right below some function being tested
+ * is arguably good for locality, so unittests end up inside
+ * templates.
+ * To make sure a template's unittests are run, it should be
+ * instantiated in the same module, e.g., some module-level
+ * unittest.
+ *
+ * Another reason for ignoring unittests in templates from non-
+ * root modules is for template codegen culling via
+ * TemplateInstance.needsCodegen(). If the compiler decides not
+ * to emit some Nullable!bool because there's an existing
+ * instantiation in some non-root module, it has no idea whether
+ * that module was compiled with -unittest too, and so whether
+ * Nullable!int (instantiated in some unittest inside the
+ * Nullable template) can be culled too. By ignoring unittests
+ * in non-root modules, the compiler won't consider any
+ * template instantiations in these unittests as candidates for
+ * further codegen culling.
+ */
+ if (mod.isRoot() && (global.params.useUnitTests || global.params.doDocComments || global.params.doHdrGeneration))
{
s = parseUnitTest(pAttrs);
if (*pLastDecl)
@@ -1530,6 +1574,8 @@ class Parser(AST) : Lexer
case TOK.return_:
stc = STC.return_;
+ if (peekNext() == TOK.scope_)
+ stc |= STC.returnScope; // recognize `return scope`
break;
case TOK.scope_:
@@ -2880,7 +2926,7 @@ class Parser(AST) : Lexer
StorageClass varargsStc;
// Attributes allowed for ...
- enum VarArgsStc = STC.const_ | STC.immutable_ | STC.shared_ | STC.scope_ | STC.return_;
+ enum VarArgsStc = STC.const_ | STC.immutable_ | STC.shared_ | STC.scope_ | STC.return_ | STC.returnScope;
check(TOK.leftParenthesis);
while (1)
@@ -2988,6 +3034,8 @@ class Parser(AST) : Lexer
case TOK.return_:
stc = STC.return_;
+ if (peekNext() == TOK.scope_)
+ stc |= STC.returnScope;
goto L2;
L2:
storageClass = appendStorageClass(storageClass, stc);
@@ -3491,7 +3539,7 @@ class Parser(AST) : Lexer
return baseclasses;
}
- private AST.Dsymbols* parseImport()
+ AST.Dsymbols* parseImport()
{
auto decldefs = new AST.Dsymbols();
Identifier aliasid = null;
@@ -4453,7 +4501,6 @@ class Parser(AST) : Lexer
private AST.Dsymbols* parseDeclarations(bool autodecl, PrefixAttributes!AST* pAttrs, const(char)* comment)
{
StorageClass storage_class = STC.undefined_;
- TOK tok = TOK.reserved;
LINK link = linkage;
Loc linkloc = this.linkLoc;
bool setAlignment = false;
@@ -4464,245 +4511,22 @@ class Parser(AST) : Lexer
if (!comment)
comment = token.blockComment.ptr;
- /* Look for AliasAssignment:
- * identifier = type;
+ /* Look for AliasReassignment
*/
if (token.value == TOK.identifier && peekNext() == TOK.assign)
- {
- const loc = token.loc;
- auto ident = token.ident;
- nextToken();
- nextToken(); // advance past =
- auto t = parseType();
- AST.Dsymbol s = new AST.AliasAssign(loc, ident, t, null);
- check(TOK.semicolon);
- addComment(s, comment);
- auto a = new AST.Dsymbols();
- a.push(s);
- return a;
- }
+ return parseAliasReassignment(comment);
+ /* Declarations that start with `alias`
+ */
+ bool isAliasDeclaration = false;
if (token.value == TOK.alias_)
{
- const loc = token.loc;
- tok = token.value;
- nextToken();
-
- /* Look for:
- * alias identifier this;
- */
- if (token.value == TOK.identifier && peekNext() == TOK.this_)
- {
- auto s = new AST.AliasThis(loc, token.ident);
- nextToken();
- check(TOK.this_);
- check(TOK.semicolon);
- auto a = new AST.Dsymbols();
- a.push(s);
- addComment(s, comment);
+ if (auto a = parseAliasDeclarations(comment))
return a;
- }
- version (none)
- {
- /* Look for:
- * alias this = identifier;
- */
- if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
- {
- check(TOK.this_);
- check(TOK.assign);
- auto s = new AliasThis(loc, token.ident);
- nextToken();
- check(TOK.semicolon);
- auto a = new Dsymbols();
- a.push(s);
- addComment(s, comment);
- return a;
- }
- }
- /* Look for:
- * alias identifier = type;
- * alias identifier(...) = type;
+ /* Handle these later:
+ * alias StorageClasses type ident;
*/
- if (token.value == TOK.identifier && hasOptionalParensThen(peek(&token), TOK.assign))
- {
- auto a = new AST.Dsymbols();
- while (1)
- {
- auto ident = token.ident;
- nextToken();
- AST.TemplateParameters* tpl = null;
- if (token.value == TOK.leftParenthesis)
- tpl = parseTemplateParameterList();
- check(TOK.assign);
-
- bool hasParsedAttributes;
- void parseAttributes()
- {
- if (hasParsedAttributes) // only parse once
- return;
- hasParsedAttributes = true;
- udas = null;
- storage_class = STC.undefined_;
- link = linkage;
- linkloc = this.linkLoc;
- setAlignment = false;
- ealign = null;
- parseStorageClasses(storage_class, link, setAlignment, ealign, udas, linkloc);
- }
-
- if (token.value == TOK.at)
- parseAttributes;
-
- AST.Declaration v;
- AST.Dsymbol s;
-
- // try to parse function type:
- // TypeCtors? BasicType ( Parameters ) MemberFunctionAttributes
- bool attributesAppended;
- const StorageClass funcStc = parseTypeCtor();
- Token* tlu = &token;
- Token* tk;
- if (token.value != TOK.function_ &&
- token.value != TOK.delegate_ &&
- isBasicType(&tlu) && tlu &&
- tlu.value == TOK.leftParenthesis)
- {
- AST.Type tret = parseBasicType();
- auto parameterList = parseParameterList(null);
-
- parseAttributes();
- if (udas)
- error("user-defined attributes not allowed for `alias` declarations");
-
- attributesAppended = true;
- storage_class = appendStorageClass(storage_class, funcStc);
- AST.Type tf = new AST.TypeFunction(parameterList, tret, link, storage_class);
- v = new AST.AliasDeclaration(loc, ident, tf);
- }
- else if (token.value == TOK.function_ ||
- token.value == TOK.delegate_ ||
- token.value == TOK.leftParenthesis &&
- skipAttributes(peekPastParen(&token), &tk) &&
- (tk.value == TOK.goesTo || tk.value == TOK.leftCurly) ||
- token.value == TOK.leftCurly ||
- 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)
- )
- {
- // function (parameters) { statements... }
- // delegate (parameters) { statements... }
- // (parameters) { statements... }
- // (parameters) => expression
- // { statements... }
- // identifier => expression
- // ref (parameters) { statements... }
- // ref (parameters) => expression
-
- s = parseFunctionLiteral();
-
- if (udas !is null)
- {
- if (storage_class != 0)
- error("Cannot put a storage-class in an alias declaration.");
- // parseAttributes shouldn't have set these variables
- assert(link == linkage && !setAlignment && ealign is null);
- auto tpl_ = cast(AST.TemplateDeclaration) s;
- assert(tpl_ !is null && tpl_.members.dim == 1);
- auto fd = cast(AST.FuncLiteralDeclaration) (*tpl_.members)[0];
- auto tf = cast(AST.TypeFunction) fd.type;
- assert(tf.parameterList.parameters.dim > 0);
- auto as = new AST.Dsymbols();
- (*tf.parameterList.parameters)[0].userAttribDecl = new AST.UserAttributeDeclaration(udas, as);
- }
-
- v = new AST.AliasDeclaration(loc, ident, s);
- }
- else
- {
- parseAttributes();
- // type
- if (udas)
- error("user-defined attributes not allowed for `%s` declarations", Token.toChars(tok));
-
- auto t = parseType();
-
- // Disallow meaningless storage classes on type aliases
- if (storage_class)
- {
- // Don't raise errors for STC that are part of a function/delegate type, e.g.
- // `alias F = ref pure nothrow @nogc @safe int function();`
- auto tp = t.isTypePointer;
- const isFuncType = (tp && tp.next.isTypeFunction) || t.isTypeDelegate;
- const remStc = isFuncType ? (storage_class & ~STC.FUNCATTR) : storage_class;
-
- if (remStc)
- {
- OutBuffer buf;
- AST.stcToBuffer(&buf, remStc);
- // @@@DEPRECATED_2.093@@@
- // Deprecated in 2020-07, can be made an error in 2.103
- deprecation("storage class `%s` has no effect in type aliases", buf.peekChars());
- }
- }
-
- v = new AST.AliasDeclaration(loc, ident, t);
- }
- if (!attributesAppended)
- storage_class = appendStorageClass(storage_class, funcStc);
- v.storage_class = storage_class;
-
- s = v;
- if (tpl)
- {
- auto a2 = new AST.Dsymbols();
- a2.push(s);
- auto tempdecl = new AST.TemplateDeclaration(loc, ident, tpl, null, a2);
- s = tempdecl;
- }
- if (link != linkage)
- {
- auto a2 = new AST.Dsymbols();
- a2.push(s);
- s = new AST.LinkDeclaration(linkloc, link, a2);
- }
- a.push(s);
-
- switch (token.value)
- {
- case TOK.semicolon:
- nextToken();
- addComment(s, comment);
- break;
-
- case TOK.comma:
- nextToken();
- addComment(s, comment);
- if (token.value != TOK.identifier)
- {
- error("identifier expected following comma, not `%s`", token.toChars());
- break;
- }
- if (peekNext() != TOK.assign && peekNext() != TOK.leftParenthesis)
- {
- error("`=` expected following identifier");
- nextToken();
- break;
- }
- continue;
-
- default:
- error("semicolon expected to close `%s` declaration", Token.toChars(tok));
- break;
- }
- break;
- }
- return a;
- }
-
- // alias StorageClasses type ident;
+ isAliasDeclaration = true;
}
AST.Type ts;
@@ -4839,7 +4663,7 @@ class Parser(AST) : Lexer
else if (!isThis && (t != AST.Type.terror))
error("no identifier for declarator `%s`", t.toChars());
- if (tok == TOK.alias_)
+ if (isAliasDeclaration)
{
AST.Declaration v;
AST.Initializer _init = null;
@@ -4852,7 +4676,7 @@ class Parser(AST) : Lexer
*/
if (udas)
- error("user-defined attributes not allowed for `%s` declarations", Token.toChars(tok));
+ error("user-defined attributes not allowed for `alias` declarations");
if (token.value == TOK.assign)
{
@@ -4901,7 +4725,7 @@ class Parser(AST) : Lexer
continue;
default:
- error("semicolon expected to close `%s` declaration", Token.toChars(tok));
+ error("semicolon expected to close `alias` declaration");
break;
}
}
@@ -5018,7 +4842,15 @@ class Parser(AST) : Lexer
continue;
default:
- error("semicolon expected, not `%s`", token.toChars());
+ if (loc.linnum != token.loc.linnum)
+ {
+ error("semicolon needed to end declaration of `%s`, instead of `%s`", v.toChars(), token.toChars());
+ errorSupplemental(loc, "`%s` declared here", v.toChars());
+ }
+ else
+ {
+ error("semicolon needed to end declaration of `%s` instead of `%s`", v.toChars(), token.toChars());
+ }
break;
}
}
@@ -5027,6 +4859,271 @@ class Parser(AST) : Lexer
return a;
}
+ /********************************
+ * Parse AliasReassignment:
+ * identifier = type;
+ * Parser is sitting on the identifier.
+ * https://dlang.org/spec/declaration.html#alias-reassignment
+ * Params:
+ * comment = if not null, comment to attach to symbol
+ * Returns:
+ * array of symbols
+ */
+ private AST.Dsymbols* parseAliasReassignment(const(char)* comment)
+ {
+ const loc = token.loc;
+ auto ident = token.ident;
+ nextToken();
+ nextToken(); // advance past =
+ auto t = parseType();
+ AST.Dsymbol s = new AST.AliasAssign(loc, ident, t, null);
+ check(TOK.semicolon);
+ addComment(s, comment);
+ auto a = new AST.Dsymbols();
+ a.push(s);
+ return a;
+ }
+
+ /********************************
+ * Parse declarations that start with `alias`
+ * Parser is sitting on the `alias`.
+ * https://dlang.org/spec/declaration.html#alias
+ * Params:
+ * comment = if not null, comment to attach to symbol
+ * Returns:
+ * array of symbols
+ */
+ private AST.Dsymbols* parseAliasDeclarations(const(char)* comment)
+ {
+ const loc = token.loc;
+ nextToken();
+ Loc linkloc = this.linkLoc;
+ AST.Expressions* udas;
+ LINK link = linkage;
+ StorageClass storage_class = STC.undefined_;
+ AST.Expression ealign;
+ bool setAlignment = false;
+
+ /* Look for:
+ * alias Identifier this;
+ * https://dlang.org/spec/class.html#alias-this
+ */
+ if (token.value == TOK.identifier && peekNext() == TOK.this_)
+ {
+ auto s = new AST.AliasThis(loc, token.ident);
+ nextToken();
+ check(TOK.this_);
+ check(TOK.semicolon);
+ auto a = new AST.Dsymbols();
+ a.push(s);
+ addComment(s, comment);
+ return a;
+ }
+ version (none)
+ {
+ /* Look for:
+ * alias this = identifier;
+ */
+ if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
+ {
+ check(TOK.this_);
+ check(TOK.assign);
+ auto s = new AliasThis(loc, token.ident);
+ nextToken();
+ check(TOK.semicolon);
+ auto a = new Dsymbols();
+ a.push(s);
+ addComment(s, comment);
+ return a;
+ }
+ }
+ /* Look for:
+ * alias identifier = type;
+ * alias identifier(...) = type;
+ * https://dlang.org/spec/declaration.html#alias
+ */
+ if (token.value == TOK.identifier && hasOptionalParensThen(peek(&token), TOK.assign))
+ {
+ auto a = new AST.Dsymbols();
+ while (1)
+ {
+ auto ident = token.ident;
+ nextToken();
+ AST.TemplateParameters* tpl = null;
+ if (token.value == TOK.leftParenthesis)
+ tpl = parseTemplateParameterList();
+ check(TOK.assign);
+
+ bool hasParsedAttributes;
+ void parseAttributes()
+ {
+ if (hasParsedAttributes) // only parse once
+ return;
+ hasParsedAttributes = true;
+ udas = null;
+ storage_class = STC.undefined_;
+ link = linkage;
+ linkloc = this.linkLoc;
+ setAlignment = false;
+ ealign = null;
+ parseStorageClasses(storage_class, link, setAlignment, ealign, udas, linkloc);
+ }
+
+ if (token.value == TOK.at)
+ parseAttributes;
+
+ AST.Declaration v;
+ AST.Dsymbol s;
+
+ // try to parse function type:
+ // TypeCtors? BasicType ( Parameters ) MemberFunctionAttributes
+ bool attributesAppended;
+ const StorageClass funcStc = parseTypeCtor();
+ Token* tlu = &token;
+ Token* tk;
+ if (token.value != TOK.function_ &&
+ token.value != TOK.delegate_ &&
+ isBasicType(&tlu) && tlu &&
+ tlu.value == TOK.leftParenthesis)
+ {
+ AST.Type tret = parseBasicType();
+ auto parameterList = parseParameterList(null);
+
+ parseAttributes();
+ if (udas)
+ error("user-defined attributes not allowed for `alias` declarations");
+
+ attributesAppended = true;
+ storage_class = appendStorageClass(storage_class, funcStc);
+ AST.Type tf = new AST.TypeFunction(parameterList, tret, link, storage_class);
+ v = new AST.AliasDeclaration(loc, ident, tf);
+ }
+ else if (token.value == TOK.function_ ||
+ token.value == TOK.delegate_ ||
+ token.value == TOK.leftParenthesis &&
+ skipAttributes(peekPastParen(&token), &tk) &&
+ (tk.value == TOK.goesTo || tk.value == TOK.leftCurly) ||
+ token.value == TOK.leftCurly ||
+ 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)
+ )
+ {
+ // function (parameters) { statements... }
+ // delegate (parameters) { statements... }
+ // (parameters) { statements... }
+ // (parameters) => expression
+ // { statements... }
+ // identifier => expression
+ // ref (parameters) { statements... }
+ // ref (parameters) => expression
+
+ s = parseFunctionLiteral();
+
+ if (udas !is null)
+ {
+ if (storage_class != 0)
+ error("Cannot put a storage-class in an alias declaration.");
+ // parseAttributes shouldn't have set these variables
+ assert(link == linkage && !setAlignment && ealign is null);
+ auto tpl_ = cast(AST.TemplateDeclaration) s;
+ assert(tpl_ !is null && tpl_.members.dim == 1);
+ auto fd = cast(AST.FuncLiteralDeclaration) (*tpl_.members)[0];
+ auto tf = cast(AST.TypeFunction) fd.type;
+ assert(tf.parameterList.parameters.dim > 0);
+ auto as = new AST.Dsymbols();
+ (*tf.parameterList.parameters)[0].userAttribDecl = new AST.UserAttributeDeclaration(udas, as);
+ }
+
+ v = new AST.AliasDeclaration(loc, ident, s);
+ }
+ else
+ {
+ parseAttributes();
+ // type
+ if (udas)
+ error("user-defined attributes not allowed for alias declarations");
+
+ auto t = parseType();
+
+ // Disallow meaningless storage classes on type aliases
+ if (storage_class)
+ {
+ // Don't raise errors for STC that are part of a function/delegate type, e.g.
+ // `alias F = ref pure nothrow @nogc @safe int function();`
+ auto tp = t.isTypePointer;
+ const isFuncType = (tp && tp.next.isTypeFunction) || t.isTypeDelegate;
+ const remStc = isFuncType ? (storage_class & ~STC.FUNCATTR) : storage_class;
+
+ if (remStc)
+ {
+ OutBuffer buf;
+ AST.stcToBuffer(&buf, remStc);
+ // @@@DEPRECATED_2.093@@@
+ // Deprecated in 2020-07, can be made an error in 2.103
+ deprecation("storage class `%s` has no effect in type aliases", buf.peekChars());
+ }
+ }
+
+ v = new AST.AliasDeclaration(loc, ident, t);
+ }
+ if (!attributesAppended)
+ storage_class = appendStorageClass(storage_class, funcStc);
+ v.storage_class = storage_class;
+
+ s = v;
+ if (tpl)
+ {
+ auto a2 = new AST.Dsymbols();
+ a2.push(s);
+ auto tempdecl = new AST.TemplateDeclaration(loc, ident, tpl, null, a2);
+ s = tempdecl;
+ }
+ if (link != linkage)
+ {
+ auto a2 = new AST.Dsymbols();
+ a2.push(s);
+ s = new AST.LinkDeclaration(linkloc, link, a2);
+ }
+ a.push(s);
+
+ switch (token.value)
+ {
+ case TOK.semicolon:
+ nextToken();
+ addComment(s, comment);
+ break;
+
+ case TOK.comma:
+ nextToken();
+ addComment(s, comment);
+ if (token.value != TOK.identifier)
+ {
+ error("identifier expected following comma, not `%s`", token.toChars());
+ break;
+ }
+ if (peekNext() != TOK.assign && peekNext() != TOK.leftParenthesis)
+ {
+ error("`=` expected following identifier");
+ nextToken();
+ break;
+ }
+ continue;
+
+ default:
+ error("semicolon expected to close `alias` declaration");
+ break;
+ }
+ break;
+ }
+ return a;
+ }
+
+ // alias StorageClasses type ident;
+ return null;
+ }
+
private AST.Dsymbol parseFunctionLiteral()
{
const loc = token.loc;
@@ -5390,6 +5487,7 @@ class Parser(AST) : Lexer
check(TOK.leftParenthesis);
auto parameters = new AST.Parameters();
+ Identifier lastai;
while (1)
{
Identifier ai = null;
@@ -5465,8 +5563,9 @@ class Parser(AST) : Lexer
if (token.value == TOK.identifier)
{
const tv = peekNext();
- if (tv == TOK.comma || tv == TOK.semicolon)
+ if (tv == TOK.comma || tv == TOK.semicolon || tv == TOK.rightParenthesis)
{
+ lastai = token.ident;
ai = token.ident;
at = null; // infer argument type
nextToken();
@@ -5486,7 +5585,17 @@ class Parser(AST) : Lexer
}
break;
}
- check(TOK.semicolon);
+ if (token.value != TOK.semicolon)
+ {
+ error("missing `; expression` before `)` of `foreach`");
+ nextToken();
+ if (lastai && parameters.length >= 2)
+ {
+ errorSupplemental(loc, "perhaps the `;` goes before `%s`", lastai.toChars());
+ }
+ return null;
+ }
+ nextToken();
AST.Expression aggr = parseExpression();
if (token.value == TOK.slice && parameters.dim == 1)
@@ -8473,6 +8582,7 @@ LagainStc:
e = new AST.FuncExp(loc, s);
break;
}
+
default:
error("expression expected, not `%s`", token.toChars());
Lerr:
@@ -8766,6 +8876,17 @@ LagainStc:
e = parsePostExp(e);
break;
}
+ case TOK.throw_:
+ {
+ nextToken();
+ // Deviation from the DIP:
+ // Parse AssignExpression instead of Expression to avoid conflicts for comma
+ // separated lists, e.g. function arguments
+ AST.Expression exp = parseAssignExp();
+ e = new AST.ThrowExp(loc, exp);
+ break;
+ }
+
default:
e = parsePrimaryExp();
e = parsePostExp(e);
diff --git a/gcc/d/dmd/parsetimevisitor.d b/gcc/d/dmd/parsetimevisitor.d
index d3e3086..7d5e19d 100644
--- a/gcc/d/dmd/parsetimevisitor.d
+++ b/gcc/d/dmd/parsetimevisitor.d
@@ -220,6 +220,7 @@ public:
void visit(AST.CallExp e) { visit(cast(AST.UnaExp)e); }
void visit(AST.DotIdExp e) { visit(cast(AST.UnaExp)e); }
void visit(AST.AssertExp e) { visit(cast(AST.UnaExp)e); }
+ void visit(AST.ThrowExp e) { visit(cast(AST.UnaExp)e); }
void visit(AST.ImportExp e) { visit(cast(AST.UnaExp)e); }
void visit(AST.DotTemplateInstanceExp e) { visit(cast(AST.UnaExp)e); }
void visit(AST.ArrayExp e) { visit(cast(AST.UnaExp)e); }
diff --git a/gcc/d/dmd/root/README.md b/gcc/d/dmd/root/README.md
index b393c12..464f338 100644
--- a/gcc/d/dmd/root/README.md
+++ b/gcc/d/dmd/root/README.md
@@ -13,6 +13,7 @@
| [hash.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/hash.d) | Calculate a hash for a byte array |
| [longdouble.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/longdouble.d) | 80-bit floating point number implementation in case they are not natively supported |
| [man.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/man.d) | Opens an online manual page |
+| [optional.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/optional.d) | Implementation of an 'Optional' type |
| [port.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/port.d) | Portable routines for functions that have different implementations on different platforms |
| [region.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/region.d) | A region allocator |
| [response.d](https://github.com/dlang/dmd/blob/master/src/dmd/root/response.d) | Parse command line arguments from response files |
diff --git a/gcc/d/dmd/root/optional.d b/gcc/d/dmd/root/optional.d
index bb8150f..f2f7389 100644
--- a/gcc/d/dmd/root/optional.d
+++ b/gcc/d/dmd/root/optional.d
@@ -1,5 +1,5 @@
/**
- * Optional implementation.
+ * Implementation of an 'Optional' type
*
* Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d
index d365049..5691f3b 100644
--- a/gcc/d/dmd/sideeffect.d
+++ b/gcc/d/dmd/sideeffect.d
@@ -94,8 +94,9 @@ extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false)
* Determine if the call of f, or function type or delegate type t1, has any side effects.
* Returns:
* 0 has any side effects
- * 1 nothrow + constant purity
- * 2 nothrow + strong purity
+ * 1 nothrow + strongly pure
+ * 2 nothrow + strongly pure + only immutable indirections in the return
+ * type
*/
int callSideEffectLevel(FuncDeclaration f)
{
@@ -106,15 +107,18 @@ int callSideEffectLevel(FuncDeclaration f)
return 0;
assert(f.type.ty == Tfunction);
TypeFunction tf = cast(TypeFunction)f.type;
- if (tf.isnothrow)
+ if (!tf.isnothrow)
+ return 0;
+ final switch (f.isPure())
{
- PURE purity = f.isPure();
- if (purity == PURE.strong)
- return 2;
- if (purity == PURE.const_)
- return 1;
+ case PURE.impure:
+ case PURE.fwdref:
+ case PURE.weak:
+ return 0;
+
+ case PURE.const_:
+ return mutabilityOfType(tf.isref, tf.next) == 2 ? 2 : 1;
}
- return 0;
}
int callSideEffectLevel(Type t)
@@ -141,10 +145,9 @@ int callSideEffectLevel(Type t)
purity = PURE.const_;
}
- if (purity == PURE.strong)
- return 2;
if (purity == PURE.const_)
- return 1;
+ return mutabilityOfType(tf.isref, tf.next) == 2 ? 2 : 1;
+
return 0;
}
@@ -178,6 +181,7 @@ private bool lambdaHasSideEffect(Expression e, bool assumeImpureCalls = false)
case EXP.remove:
case EXP.assert_:
case EXP.halt:
+ case EXP.throw_:
case EXP.delete_:
case EXP.new_:
case EXP.newAnonymousClass:
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index be568f5..8b271f8 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -21,7 +21,6 @@ import dmd.arraytypes;
import dmd.astenums;
import dmd.ast_node;
import dmd.gluelayer;
-import dmd.canthrow;
import dmd.cond;
import dmd.dclass;
import dmd.declaration;
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index dfb65a1..66eddd8 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -45,7 +45,7 @@ struct code;
/* How a statement exits; this is returned by blockExit()
*/
-enum BE
+enum BE : int32_t
{
BEnone = 0,
BEfallthru = 1,
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index faeba11..1f7f3e4 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -122,8 +122,10 @@ private LabelStatement checkLabeledLoop(Scope* sc, Statement statement)
* Returns:
* `e` or ErrorExp.
*/
-private Expression checkAssignmentAsCondition(Expression e)
+private Expression checkAssignmentAsCondition(Expression e, Scope* sc)
{
+ if (sc.flags & SCOPE.Cfile)
+ return e;
auto ec = lastComma(e);
if (ec.op == EXP.assign)
{
@@ -148,7 +150,7 @@ extern(C++) Statement statementSemantic(Statement s, Scope* sc)
return v.result;
}
-private extern (C++) final class StatementSemanticVisitor : Visitor
+package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
{
alias visit = Visitor.visit;
@@ -550,7 +552,7 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
(cast(DotIdExp)ds.condition).noderef = true;
// check in syntax level
- ds.condition = checkAssignmentAsCondition(ds.condition);
+ ds.condition = checkAssignmentAsCondition(ds.condition, sc);
ds.condition = ds.condition.expressionSemantic(sc);
ds.condition = resolveProperties(sc, ds.condition);
@@ -623,7 +625,7 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
(cast(DotIdExp)fs.condition).noderef = true;
// check in syntax level
- fs.condition = checkAssignmentAsCondition(fs.condition);
+ fs.condition = checkAssignmentAsCondition(fs.condition, sc);
fs.condition = fs.condition.expressionSemantic(sc);
fs.condition = resolveProperties(sc, fs.condition);
@@ -1867,7 +1869,7 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
*/
// check in syntax level
- ifs.condition = checkAssignmentAsCondition(ifs.condition);
+ ifs.condition = checkAssignmentAsCondition(ifs.condition, sc);
auto sym = new ScopeDsymbol();
sym.parent = sc.scopesym;
@@ -3732,44 +3734,61 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
*/
//printf("ThrowStatement::semantic()\n");
+ if (throwSemantic(ts.loc, ts.exp, sc))
+ result = ts;
+ else
+ setError();
+
+ }
+ /**
+ * Run semantic on `throw <exp>`.
+ *
+ * Params:
+ * loc = location of the `throw`
+ * exp = value to be thrown
+ * sc = enclosing scope
+ *
+ * Returns: true if the `throw` is valid, or false if an error was found
+ */
+ extern(D) static bool throwSemantic(const ref Loc loc, ref Expression exp, Scope* sc)
+ {
if (!global.params.useExceptions)
{
- ts.error("Cannot use `throw` statements with -betterC");
- return setError();
+ loc.error("Cannot use `throw` statements with -betterC");
+ return false;
}
if (!ClassDeclaration.throwable)
{
- ts.error("Cannot use `throw` statements because `object.Throwable` was not declared");
- return setError();
+ loc.error("Cannot use `throw` statements because `object.Throwable` was not declared");
+ return false;
}
- FuncDeclaration fd = sc.parent.isFuncDeclaration();
- fd.hasReturnExp |= 2;
+ if (FuncDeclaration fd = sc.parent.isFuncDeclaration())
+ fd.hasReturnExp |= 2;
- if (ts.exp.op == EXP.new_)
+ if (exp.op == EXP.new_)
{
- NewExp ne = cast(NewExp)ts.exp;
+ NewExp ne = cast(NewExp) exp;
ne.thrownew = true;
}
- ts.exp = ts.exp.expressionSemantic(sc);
- ts.exp = resolveProperties(sc, ts.exp);
- ts.exp = checkGC(sc, ts.exp);
- if (ts.exp.op == EXP.error)
- return setError();
+ exp = exp.expressionSemantic(sc);
+ exp = resolveProperties(sc, exp);
+ exp = checkGC(sc, exp);
+ if (exp.op == EXP.error)
+ return false;
- checkThrowEscape(sc, ts.exp, false);
+ checkThrowEscape(sc, exp, false);
- ClassDeclaration cd = ts.exp.type.toBasetype().isClassHandle();
+ ClassDeclaration cd = exp.type.toBasetype().isClassHandle();
if (!cd || ((cd != ClassDeclaration.throwable) && !ClassDeclaration.throwable.isBaseOf(cd, null)))
{
- ts.error("can only throw class objects derived from `Throwable`, not type `%s`", ts.exp.type.toChars());
- return setError();
+ loc.error("can only throw class objects derived from `Throwable`, not type `%s`", exp.type.toChars());
+ return false;
}
-
- result = ts;
+ return true;
}
override void visit(DebugStatement ds)
diff --git a/gcc/d/dmd/staticcond.d b/gcc/d/dmd/staticcond.d
index 6ff166a..0cbdd96 100644
--- a/gcc/d/dmd/staticcond.d
+++ b/gcc/d/dmd/staticcond.d
@@ -109,18 +109,16 @@ bool evalStaticCondition(Scope* sc, Expression original, Expression e, out bool
e = e.ctfeInterpret();
const opt = e.toBool();
- if (opt.hasValue(true))
- return true;
- else if (opt.hasValue(false))
+ if (opt.isEmpty())
{
- if (negatives)
- negatives.push(before);
+ e.error("expression `%s` is not constant", e.toChars());
+ errors = true;
return false;
}
- e.error("expression `%s` is not constant", e.toChars());
- errors = true;
- return false;
+ if (negatives && !opt.get())
+ negatives.push(before);
+ return opt.get();
}
return impl(e);
}
diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d
index 619304d..e954625 100644
--- a/gcc/d/dmd/target.d
+++ b/gcc/d/dmd/target.d
@@ -61,8 +61,8 @@ extern (C++) struct Target
import dmd.dscope : Scope;
import dmd.expression : Expression;
import dmd.func : FuncDeclaration;
- import dmd.globals : LINK, Loc, d_int64;
- import dmd.astenums : TY;
+ import dmd.globals : Loc, d_int64;
+ import dmd.astenums : LINK, TY;
import dmd.mtype : Type, TypeFunction, TypeTuple;
import dmd.root.ctfloat : real_t;
import dmd.statement : Statement;
@@ -119,7 +119,7 @@ extern (C++) struct Target
const(char)[] lib_ext; /// extension for static library files
const(char)[] dll_ext; /// extension for dynamic library files
bool run_noext; /// allow -run sources without extensions
- bool mscoff = false; // for Win32: write MsCoff object files instead of OMF
+ bool omfobj = false; // for Win32: write OMF object files instead of MsCoff
/**
* Values representing all properties for floating point types
*/
@@ -293,6 +293,13 @@ extern (C++) struct Target
* `false` if the target backend handles synchronizing monitors.
*/
extern (C++) bool libraryObjectMonitors(FuncDeclaration fd, Statement fbody);
+
+ /**
+ * Returns true if the target supports `pragma(linkerDirective)`.
+ * Returns:
+ * `false` if the target does not support `pragma(linkerDirective)`.
+ */
+ extern (C++) bool supportsLinkerDirective() const;
}
////////////////////////////////////////////////////////////////////////////////
@@ -340,7 +347,7 @@ struct TargetCPP
import dmd.dsymbol : Dsymbol;
import dmd.dclass : ClassDeclaration;
import dmd.func : FuncDeclaration;
- import dmd.mtype : Parameter, Type;
+ import dmd.mtype : Type;
enum Runtime : ubyte
{
@@ -354,6 +361,7 @@ struct TargetCPP
bool reverseOverloads; /// set if overloaded functions are grouped and in reverse order (such as in dmc and cl)
bool exceptions; /// set if catching C++ exceptions is supported
bool twoDtorInVtable; /// target C++ ABI puts deleting and non-deleting destructor into vtable
+ bool splitVBasetable; /// set if C++ ABI uses separate tables for virtual functions and virtual bases
bool wrapDtorInExternD; /// set if C++ dtors require a D wrapper to be callable from runtime
Runtime runtime; /// vendor of the C++ runtime to link against
@@ -398,13 +406,13 @@ struct TargetCPP
/**
* Get the type that will really be used for passing the given argument
- * to an `extern(C++)` function.
+ * to an `extern(C++)` function, or `null` if unhandled.
* Params:
- * p = parameter to be passed.
+ * t = type to be passed.
* Returns:
- * `Type` to use for parameter `p`.
+ * `Type` to use for type `t`.
*/
- extern (C++) Type parameterType(Parameter p);
+ extern (C++) Type parameterType(Type t);
/**
* Checks whether type is a vendor-specific fundamental type.
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index 9c879de..fdae14c 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -20,7 +20,6 @@ class ClassDeclaration;
class Dsymbol;
class Expression;
class FuncDeclaration;
-class Parameter;
class Statement;
class Type;
class TypeTuple;
@@ -92,6 +91,7 @@ struct TargetCPP
bool reverseOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order
bool exceptions; // set if catching C++ exceptions is supported
bool twoDtorInVtable; // target C++ ABI puts deleting and non-deleting destructor into vtable
+ bool splitVBasetable; // set if C++ ABI uses separate tables for virtual functions and virtual bases
bool wrapDtorInExternD; // set if C++ dtors require a D wrapper to be callable from runtime
Runtime runtime;
@@ -99,7 +99,7 @@ struct TargetCPP
const char *typeInfoMangle(ClassDeclaration *cd);
const char *thunkMangle(FuncDeclaration *fd, int offset);
const char *typeMangle(Type *t);
- Type *parameterType(Parameter *p);
+ Type *parameterType(Type *p);
bool fundamentalType(const Type *t, bool& isFundamental);
unsigned derivedClassOffset(ClassDeclaration *baseClass);
};
@@ -160,7 +160,7 @@ struct Target
DString lib_ext; /// extension for static library files
DString dll_ext; /// extension for dynamic library files
bool run_noext; /// allow -run sources without extensions
- bool mscoff; /// for Win32: write COFF object files instead of OMF
+ bool omfobj; /// for Win32: write OMF object files instead of COFF
template <typename T>
struct FPTypeProperties
@@ -205,6 +205,7 @@ public:
Expression *getTargetInfo(const char* name, const Loc& loc);
bool isCalleeDestroyingArgs(TypeFunction* tf);
bool libraryObjectMonitors(FuncDeclaration *fd, Statement *fbody);
+ bool supportsLinkerDirective() const;
void addPredefinedGlobalIdentifiers() const;
};
diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h
index 95cd349..42517f6 100644
--- a/gcc/d/dmd/template.h
+++ b/gcc/d/dmd/template.h
@@ -284,6 +284,7 @@ public:
Identifier *getIdent();
hash_t toHash();
+ bool isDiscardable();
bool needsCodegen();
TemplateInstance *isTemplateInstance() { return this; }
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index 5830dbb..20b8711 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -278,6 +278,7 @@ enum TOK : ubyte
_Thread_local,
// C only extended keywords
+ _import,
__cdecl,
__declspec,
__attribute__,
@@ -585,6 +586,7 @@ private immutable TOK[] keywords =
TOK._Thread_local,
// C only extended keywords
+ TOK._import,
TOK.__cdecl,
TOK.__declspec,
TOK.__attribute__,
@@ -615,7 +617,7 @@ static immutable TOK[TOK.max + 1] Ckeywords =
restrict, return_, int16, signed, sizeof_, static_, struct_, switch_, typedef_,
union_, unsigned, void_, volatile, while_, asm_,
_Alignas, _Alignof, _Atomic, _Bool, _Complex, _Generic, _Imaginary, _Noreturn,
- _Static_assert, _Thread_local, __cdecl, __declspec, __attribute__ ];
+ _Static_assert, _Thread_local, _import, __cdecl, __declspec, __attribute__ ];
foreach (kw; Ckwds)
tab[kw] = cast(TOK) kw;
@@ -891,6 +893,7 @@ extern (C++) struct Token
TOK._Thread_local : "_Thread_local",
// C only extended keywords
+ TOK._import : "__import",
TOK.__cdecl : "__cdecl",
TOK.__declspec : "__declspec",
TOK.__attribute__ : "__attribute__",
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index 0a00ae7..a7c9aa5 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -287,6 +287,7 @@ enum class TOK : unsigned char
_Thread_local_,
// C only extended keywords
+ _import,
cdecl,
declspec,
attribute__,
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index ae8ab9b..ec86bc5 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -150,6 +150,7 @@ shared static this()
"hasPostblit",
"hasCopyConstructor",
"isCopyable",
+ "parameters"
];
StringTable!(bool)* stringTable = cast(StringTable!(bool)*) &traitsStringTable;
@@ -998,7 +999,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
e.error("`bool` expected as third argument of `__traits(getOverloads)`, not `%s` of type `%s`", b.toChars(), b.type.toChars());
return ErrorExp.get();
}
- includeTemplates = b.toBool().hasValue(true);
+ includeTemplates = b.toBool().get();
}
StringExp se = ex.toStringExp();
@@ -2090,7 +2091,43 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
auto tup = new TupleExp(e.loc, exps);
return tup.expressionSemantic(sc);
}
+ //https://issues.dlang.org/show_bug.cgi?id=22291
+ if (e.ident == Id.parameters)
+ {
+ //No args are valid
+ if (e.args)
+ {
+ char[] contents = cast(char[]) e.args.toString();
+ contents = contents[1..$];
+ contents[$-1] = '\0';
+ e.error("`__traits(parameters)` cannot have arguments, but `%s` was supplied", contents.ptr);
+ return ErrorExp.get();
+ }
+ if (sc.func is null)
+ {
+ e.error("`__traits(parameters)` may only be used inside a function");
+ return ErrorExp.get();
+ }
+ assert(sc.func && sc.parent.isFuncDeclaration());
+ auto tf = sc.parent.isFuncDeclaration.type.isTypeFunction();
+ assert(tf);
+ auto exps = new Expressions(0);
+ int addParameterDG(size_t idx, Parameter x)
+ {
+ assert(x.ident);
+ exps.push(new IdentifierExp(e.loc, x.ident));
+ return 0;
+ }
+ /*
+ This is required since not all "parameters" actually have a name
+ until they (tuples) are expanded e.g. an anonymous tuple parameter's
+ contents get given names but not the tuple itself.
+ */
+ Parameter._foreach(tf.parameterList.parameters, &addParameterDG);
+ auto tup = new TupleExp(e.loc, exps);
+ return tup.expressionSemantic(sc);
+ }
static const(char)[] trait_search_fp(const(char)[] seed, out int cost)
{
//printf("trait_search_fp('%s')\n", seed);
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index 0479d5a..8b6ca65 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -1141,6 +1141,12 @@ package mixin template ParseVisitMethods(AST)
}
}
+ override void visit(AST.ThrowExp e)
+ {
+ //printf("Visiting ThrowExp\n");
+ e.e1.accept(this);
+ }
+
// Template Parameter
//===========================================================
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 34b363d..e11f1f7 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -2062,7 +2062,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
switch (mtype.tok)
{
case TOK.enum_:
- auto ed = new EnumDeclaration(mtype.loc, mtype.id, Type.tint32);
+ auto ed = new EnumDeclaration(mtype.loc, mtype.id, mtype.base);
declare(ed);
mtype.resolved = visitEnum(new TypeEnum(ed));
break;
@@ -3940,7 +3940,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
e = new TupleExp(e.loc, e0, exps);
Scope* sc2 = sc.push();
- sc2.flags |= global.params.useDIP1000 == FeatureState.enabled ? SCOPE.onlysafeaccess : SCOPE.noaccesscheck;
+ sc2.flags |= SCOPE.noaccesscheck;
e = e.expressionSemantic(sc2);
sc2.pop();
return e;
@@ -4201,7 +4201,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
e = new TupleExp(e.loc, e0, exps);
Scope* sc2 = sc.push();
- sc2.flags |= global.params.useDIP1000 == FeatureState.enabled ? SCOPE.onlysafeaccess : SCOPE.noaccesscheck;
+ sc2.flags |= SCOPE.noaccesscheck;
e = e.expressionSemantic(sc2);
sc2.pop();
return e;
diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h
index 5bad56b..5d6b94c 100644
--- a/gcc/d/dmd/visitor.h
+++ b/gcc/d/dmd/visitor.h
@@ -220,6 +220,7 @@ class BinAssignExp;
class MixinExp;
class ImportExp;
class AssertExp;
+class ThrowExp;
class DotIdExp;
class DotTemplateExp;
class DotVarExp;
@@ -511,6 +512,7 @@ public:
virtual void visit(CallExp *e) { visit((UnaExp *)e); }
virtual void visit(DotIdExp *e) { visit((UnaExp *)e); }
virtual void visit(AssertExp *e) { visit((UnaExp *)e); }
+ virtual void visit(ThrowExp *e) { visit((UnaExp *)e); }
virtual void visit(ImportExp *e) { visit((UnaExp *)e); }
virtual void visit(DotTemplateInstanceExp *e) { visit((UnaExp *)e); }
virtual void visit(ArrayExp *e) { visit((UnaExp *)e); }
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index f8d6876..dd7ebc8 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -1186,6 +1186,14 @@ public:
this->result_ = build_assign (modifycode, t1, t2);
}
+ /* Build a throw expression. */
+
+ void visit (ThrowExp *e)
+ {
+ tree arg = build_expr_dtor (e->e1);
+ this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
+ }
+
/* Build a postfix expression. */
void visit (PostExp *e)
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 4b6d245..8ae6ea1 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -274,6 +274,72 @@ insert_aggregate_field (tree type, tree field, size_t offset)
TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), field);
}
+/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */
+
+static tree
+d_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
+{
+ /* Same as d_type_for_size, but uses exact match for size. */
+ if (width == TYPE_PRECISION (d_byte_type))
+ return unsignedp ? d_ubyte_type : d_byte_type;
+
+ if (width == TYPE_PRECISION (d_short_type))
+ return unsignedp ? d_ushort_type : d_short_type;
+
+ if (width == TYPE_PRECISION (d_int_type))
+ return unsignedp ? d_uint_type : d_int_type;
+
+ if (width == TYPE_PRECISION (d_long_type))
+ return unsignedp ? d_ulong_type : d_long_type;
+
+ if (width == TYPE_PRECISION (d_cent_type))
+ return unsignedp ? d_ucent_type : d_cent_type;
+
+ for (int i = 0; i < NUM_INT_N_ENTS; i ++)
+ {
+ if (int_n_enabled_p[i] && width == int_n_data[i].bitsize)
+ {
+ if (unsignedp)
+ return int_n_trees[i].unsigned_type;
+ else
+ return int_n_trees[i].signed_type;
+ }
+ }
+
+ return build_nonstandard_integer_type (width, unsignedp);
+}
+
+/* Adds BITFIELD into the aggregate TYPE at OFFSET+BITOFFSET. */
+
+static void
+insert_aggregate_bitfield (tree type, tree bitfield, size_t width,
+ size_t offset, size_t bitoffset)
+{
+ DECL_FIELD_CONTEXT (bitfield) = type;
+ SET_DECL_OFFSET_ALIGN (bitfield, TYPE_ALIGN (TREE_TYPE (bitfield)));
+ DECL_SIZE (bitfield) = bitsize_int (width);
+ DECL_FIELD_OFFSET (bitfield) = size_int (offset);
+ DECL_FIELD_BIT_OFFSET (bitfield) = bitsize_int (bitoffset);
+
+ TREE_ADDRESSABLE (bitfield) = TYPE_SHARED (TREE_TYPE (bitfield));
+
+ DECL_BIT_FIELD (bitfield) = 1;
+ DECL_BIT_FIELD_TYPE (bitfield) = TREE_TYPE (bitfield);
+
+ layout_decl (bitfield, 0);
+
+ /* Give bit-field its proper type after layout_decl. */
+ tree orig_type = DECL_BIT_FIELD_TYPE (bitfield);
+ if (width != TYPE_PRECISION (orig_type))
+ {
+ TREE_TYPE (bitfield)
+ = d_build_bitfield_integer_type (width, TYPE_UNSIGNED (orig_type));
+ SET_DECL_MODE (bitfield, TYPE_MODE (TREE_TYPE (bitfield)));
+ }
+
+ TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), bitfield);
+}
+
/* For all decls in the FIELDS chain, adjust their field offset by OFFSET.
This is done as the frontend puts fields into the outer struct, and so
their offset is from the beginning of the aggregate.
@@ -356,7 +422,16 @@ layout_aggregate_members (Dsymbols *members, tree context, bool inherited_p)
tree field = create_field_decl (declaration_type (var), ident,
inherited_p, inherited_p);
apply_user_attributes (var, field);
- insert_aggregate_field (context, field, var->offset);
+
+ if (BitFieldDeclaration *bf = var->isBitFieldDeclaration ())
+ {
+ /* Bit-fields come from an ImportC context, and require the
+ field be correctly adjusted. */
+ insert_aggregate_bitfield (context, field, bf->fieldWidth,
+ bf->offset, bf->bitOffset);
+ }
+ else
+ insert_aggregate_field (context, field, var->offset);
/* Because the front-end shares field decls across classes, don't
create the corresponding back-end symbol unless we are adding
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b49ba22..e1a00c8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5641,8 +5641,10 @@ warns that an unrecognized option is present.
The effectiveness of some warnings depends on optimizations also being
enabled. For example @option{-Wsuggest-final-types} is more effective
-with link-time optimization and @option{-Wmaybe-uninitialized} does not
-warn at all unless optimization is enabled.
+with link-time optimization and some instances of other warnings may
+not be issued at all unless optimization is enabled. While optimization
+in general improves the efficacy of control and data flow sensitive
+warnings, in some cases it may also cause false positives.
@table @gcctabopt
@item -Wpedantic
@@ -7691,20 +7693,22 @@ void f (char c, int i)
@itemx -Warray-bounds=@var{n}
@opindex Wno-array-bounds
@opindex Warray-bounds
-This option is only active when @option{-ftree-vrp} is active
-(default for @option{-O2} and above). It warns about subscripts to arrays
-that are always out of bounds. This warning is enabled by @option{-Wall}.
+Warn about out of bounds subscripts or offsets into arrays. This warning
+is enabled by @option{-Wall}. It is more effective when @option{-ftree-vrp}
+is active (the default for @option{-O2} and above) but a subset of instances
+are issued even without optimization.
@table @gcctabopt
@item -Warray-bounds=1
-This is the warning level of @option{-Warray-bounds} and is enabled
+This is the default warning level of @option{-Warray-bounds} and is enabled
by @option{-Wall}; higher levels are not, and must be explicitly requested.
@item -Warray-bounds=2
-This warning level also warns about out of bounds access for
-arrays at the end of a struct and for arrays accessed through
-pointers. This warning level may give a larger number of
-false positives and is deactivated by default.
+This warning level also warns about out of bounds accesses to trailing
+struct members of one-element array types (@pxref{Zero Length}) and about
+the intermediate results of pointer arithmetic that may yield out of bounds
+values. This warning level may give a larger number of false positives and
+is deactivated by default.
@end table
@item -Warray-compare
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 386d573..7b21240 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -8643,7 +8643,7 @@ native_interpret_fixed (tree type, const unsigned char *ptr, int len)
the buffer PTR of length LEN as a REAL_CST of type TYPE.
If the buffer cannot be interpreted, return NULL_TREE. */
-static tree
+tree
native_interpret_real (tree type, const unsigned char *ptr, int len)
{
scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type);
@@ -8694,19 +8694,7 @@ native_interpret_real (tree type, const unsigned char *ptr, int len)
}
real_from_target (&r, tmp, mode);
- tree ret = build_real (type, r);
- if (MODE_COMPOSITE_P (mode))
- {
- /* For floating point values in composite modes, punt if this folding
- doesn't preserve bit representation. As the mode doesn't have fixed
- precision while GCC pretends it does, there could be valid values that
- GCC can't really represent accurately. See PR95450. */
- unsigned char buf[24];
- if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes
- || memcmp (ptr, buf, total_bytes) != 0)
- ret = NULL_TREE;
- }
- return ret;
+ return build_real (type, r);
}
@@ -8824,7 +8812,23 @@ native_interpret_expr (tree type, const unsigned char *ptr, int len)
return native_interpret_int (type, ptr, len);
case REAL_TYPE:
- return native_interpret_real (type, ptr, len);
+ if (tree ret = native_interpret_real (type, ptr, len))
+ {
+ /* For floating point values in composite modes, punt if this
+ folding doesn't preserve bit representation. As the mode doesn't
+ have fixed precision while GCC pretends it does, there could be
+ valid values that GCC can't really represent accurately.
+ See PR95450. Even for other modes, e.g. x86 XFmode can have some
+ bit combinationations which GCC doesn't preserve. */
+ unsigned char buf[24];
+ scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type);
+ int total_bytes = GET_MODE_SIZE (mode);
+ if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes
+ || memcmp (ptr, buf, total_bytes) != 0)
+ return NULL_TREE;
+ return ret;
+ }
+ return NULL_TREE;
case FIXED_POINT_TYPE:
return native_interpret_fixed (type, ptr, len);
@@ -14208,11 +14212,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap)
&& multiple_of_p (type, TREE_OPERAND (top, 2), bottom, nowrap));
case INTEGER_CST:
- if (TREE_CODE (bottom) != INTEGER_CST
- || integer_zerop (bottom)
- || (TYPE_UNSIGNED (type)
- && (tree_int_cst_sgn (top) < 0
- || tree_int_cst_sgn (bottom) < 0)))
+ if (TREE_CODE (bottom) != INTEGER_CST || integer_zerop (bottom))
return 0;
return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom),
SIGNED);
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index f217598..926c775 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -36,6 +36,7 @@ extern int native_encode_expr (const_tree, unsigned char *, int, int off = -1);
extern int native_encode_initializer (tree, unsigned char *, int,
int off = -1, unsigned char * = nullptr);
extern tree native_interpret_expr (tree, const unsigned char *, int);
+extern tree native_interpret_real (tree, const unsigned char *, int);
extern bool can_native_interpret_type_p (tree);
extern tree native_interpret_aggregate (tree, const unsigned char *, int, int);
extern tree find_bitfield_repr_type (int, int);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 4a1e6c6..4a1371b 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,27 @@
+2022-02-15 Tobias Burnus <tobias@codesourcery.com>
+
+ * trans-openmp.cc (gfc_trans_omp_depobj): Fix to alloc/ptr dummy
+ and for c_ptr.
+
+2022-02-15 Tobias Burnus <tobias@codesourcery.com>
+
+ * trans-openmp.cc (gfc_trans_omp_clauses, gfc_trans_omp_depobj):
+ Depend on the proper addr, for ptr/alloc depend on pointee.
+
+2022-02-14 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104211
+ * expr.cc (find_array_section): Replace assertion by error
+ recovery when encountering bad array constructor.
+
+2022-02-13 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/104228
+ * resolve.cc (resolve_assoc_var): Also create a new character
+ length for non-dummy associate targets.
+ * trans-stmt.cc (trans_associate_var): Initialize character length
+ even if no temporary is used for the associate variable.
+
2022-02-10 Roger Sayle <roger@nextmovesoftware.com>
Tobias Burnus <tobias@codesourcery.com>
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index ed82a94..c9c0ba4 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -1718,7 +1718,13 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
}
cons = gfc_constructor_lookup (base, limit);
- gcc_assert (cons);
+ if (cons == NULL)
+ {
+ gfc_error ("Error in array constructor referenced at %L",
+ &ref->u.ar.where);
+ t = false;
+ goto cleanup;
+ }
gfc_constructor_append_expr (&expr->value.constructor,
gfc_copy_expr (cons->expr), NULL);
}
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 0eba0b3..4d56a771 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -2881,15 +2881,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
tree decl = gfc_trans_omp_variable (n->sym, false);
if (gfc_omp_privatize_by_reference (decl))
decl = build_fold_indirect_ref (decl);
- if (n->u.depend_op == OMP_DEPEND_DEPOBJ
- && POINTER_TYPE_P (TREE_TYPE (decl)))
- decl = build_fold_indirect_ref (decl);
if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
{
decl = gfc_conv_descriptor_data_get (decl);
gcc_assert (POINTER_TYPE_P (TREE_TYPE (decl)));
decl = build_fold_indirect_ref (decl);
}
+ else if (n->sym->attr.allocatable || n->sym->attr.pointer)
+ decl = build_fold_indirect_ref (decl);
else if (DECL_P (decl))
TREE_ADDRESSABLE (decl) = 1;
OMP_CLAUSE_DECL (node) = decl;
@@ -5508,12 +5507,46 @@ gfc_trans_omp_depobj (gfc_code *code)
if (n)
{
tree var;
- if (n->expr)
- var = gfc_convert_expr_to_tree (&block, n->expr);
+ if (n->expr && n->expr->ref->u.ar.type != AR_FULL)
+ {
+ gfc_init_se (&se, NULL);
+ if (n->expr->ref->u.ar.type == AR_ELEMENT)
+ {
+ gfc_conv_expr_reference (&se, n->expr);
+ var = se.expr;
+ }
+ else
+ {
+ gfc_conv_expr_descriptor (&se, n->expr);
+ var = gfc_conv_array_data (se.expr);
+ }
+ gfc_add_block_to_block (&block, &se.pre);
+ gfc_add_block_to_block (&block, &se.post);
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (var)));
+ }
else
- var = gfc_get_symbol_decl (n->sym);
- if (!POINTER_TYPE_P (TREE_TYPE (var)))
- var = gfc_build_addr_expr (NULL, var);
+ {
+ var = gfc_get_symbol_decl (n->sym);
+ if (POINTER_TYPE_P (TREE_TYPE (var))
+ && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (var))))
+ var = build_fold_indirect_ref (var);
+ if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (var)))
+ {
+ var = gfc_conv_descriptor_data_get (var);
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (var)));
+ }
+ else if ((n->sym->attr.allocatable || n->sym->attr.pointer)
+ && n->sym->attr.dummy)
+ var = build_fold_indirect_ref (var);
+ else if (!POINTER_TYPE_P (TREE_TYPE (var))
+ || (n->sym->ts.f90_type == BT_VOID
+ && !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (var)))
+ && !GFC_ARRAY_TYPE_P (TREE_TYPE (TREE_TYPE (var)))))
+ {
+ TREE_ADDRESSABLE (var) = 1;
+ var = gfc_build_addr_expr (NULL, var);
+ }
+ }
depobj = save_expr (depobj);
tree r = build_fold_indirect_ref_loc (loc, depobj);
gfc_add_expr_to_block (&block,
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index d9b1a44..16f02c2 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -4807,10 +4807,10 @@ clear_padding_type (clear_padding_struct *buf, tree type,
clear_padding_flush (buf, false);
if (clear_padding_real_needs_padding_p (type))
{
- /* Use native_interpret_expr + native_encode_expr to figure out
+ /* Use native_interpret_real + native_encode_expr to figure out
which bits are padding. */
memset (buf->buf + buf->size, ~0, sz);
- tree cst = native_interpret_expr (type, buf->buf + buf->size, sz);
+ tree cst = native_interpret_real (type, buf->buf + buf->size, sz);
gcc_assert (cst && TREE_CODE (cst) == REAL_CST);
int len = native_encode_expr (cst, buf->buf + buf->size, sz);
gcc_assert (len > 0 && (size_t) len == (size_t) sz);
diff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc
index d9a7772..e33dd90 100644
--- a/gcc/gimple-loop-jam.cc
+++ b/gcc/gimple-loop-jam.cc
@@ -198,7 +198,8 @@ unroll_jam_possible_p (class loop *outer, class loop *loop)
if (!empty_block_p (loop->latch))
return false;
- if (!single_exit (loop))
+ edge exit;
+ if (!(exit = single_exit (loop)))
return false;
/* We need a perfect nest. Quick check for adjacent inner loops. */
@@ -259,7 +260,12 @@ unroll_jam_possible_p (class loop *outer, class loop *loop)
n = get_loop_body_with_size (outer, bbs, n_basic_blocks_for_fn (cfun));
for (i = 0; i < n; i++)
- if (bbs[i]->loop_father == outer && bb_prevents_fusion_p (bbs[i]))
+ if (bbs[i]->loop_father == outer
+ && (bb_prevents_fusion_p (bbs[i])
+ /* Outer loop exits must come after the inner loop, otherwise
+ we'll put the outer loop exit into the fused inner loop. */
+ || (loop_exits_from_bb_p (outer, bbs[i])
+ && !dominated_by_p (CDI_DOMINATORS, bbs[i], exit->src))))
break;
free (bbs);
if (i != n)
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 5133a43..2fc8376 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -1270,6 +1270,18 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
src.get_operand (range1, op1);
src.get_operand (range2, op2);
+ // Try to see if there is a dependence between the COND and either operand
+ if (src.gori ())
+ if (src.gori ()->condexpr_adjust (range1, range2, s, cond, op1, op2, src))
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Possible COND_EXPR adjustment. Range op1 : ");
+ range1.dump(dump_file);
+ fprintf (dump_file, " and Range op2: ");
+ range2.dump(dump_file);
+ fprintf (dump_file, "\n");
+ }
+
// If the condition is known, choose the appropriate expression.
if (cond_range.singleton_p ())
{
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 3e53283..311214c 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -334,7 +334,7 @@ range_def_chain::get_def_chain (tree name)
unsigned v = SSA_NAME_VERSION (name);
// If it has already been processed, just return the cached value.
- if (has_def_chain (name))
+ if (has_def_chain (name) && m_def_chain[v].bm)
return m_def_chain[v].bm;
// No definition chain for default defs.
@@ -1303,6 +1303,100 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
return false;
}
+// Given COND ? OP1 : OP2 with ranges R1 for OP1 and R2 for OP2, Use gori
+// to further resolve R1 and R2 if there are any dependencies between
+// OP1 and COND or OP2 and COND. All values can are to be calculated using SRC
+// as the origination source location for operands..
+// Effectively, use COND an the edge condition and solve for OP1 on the true
+// edge and OP2 on the false edge.
+
+bool
+gori_compute::condexpr_adjust (irange &r1, irange &r2, gimple *, tree cond,
+ tree op1, tree op2, fur_source &src)
+{
+ int_range_max tmp, cond_true, cond_false;
+ tree ssa1 = gimple_range_ssa_p (op1);
+ tree ssa2 = gimple_range_ssa_p (op2);
+ if (!ssa1 && !ssa2)
+ return false;
+ if (!COMPARISON_CLASS_P (cond))
+ return false;
+ tree type = TREE_TYPE (TREE_OPERAND (cond, 0));
+ if (!range_compatible_p (type, TREE_TYPE (TREE_OPERAND (cond, 1))))
+ return false;
+ range_operator *hand = range_op_handler (TREE_CODE (cond), type);
+ if (!hand)
+ return false;
+
+ tree c1 = gimple_range_ssa_p (TREE_OPERAND (cond, 0));
+ tree c2 = gimple_range_ssa_p (TREE_OPERAND (cond, 1));
+
+ // Only solve if there is one SSA name in the condition.
+ if ((!c1 && !c2) || (c1 && c2))
+ return false;
+
+ // Pick up the current values of each part of the condition.
+ int_range_max cl, cr;
+ src.get_operand (cl, TREE_OPERAND (cond, 0));
+ src.get_operand (cr, TREE_OPERAND (cond, 1));
+
+ tree cond_name = c1 ? c1 : c2;
+ gimple *def_stmt = SSA_NAME_DEF_STMT (cond_name);
+
+ // Evaluate the value of COND_NAME on the true and false edges, using either
+ // the op1 or op2 routines based on its location.
+ if (c1)
+ {
+ if (!hand->op1_range (cond_false, type, m_bool_zero, cr))
+ return false;
+ if (!hand->op1_range (cond_true, type, m_bool_one, cr))
+ return false;
+ cond_false.intersect (cl);
+ cond_true.intersect (cl);
+ }
+ else
+ {
+ if (!hand->op2_range (cond_false, type, m_bool_zero, cl))
+ return false;
+ if (!hand->op2_range (cond_true, type, m_bool_one, cl))
+ return false;
+ cond_false.intersect (cr);
+ cond_true.intersect (cr);
+ }
+
+ unsigned idx;
+ if ((idx = tracer.header ("cond_expr evaluation : ")))
+ {
+ fprintf (dump_file, " range1 = ");
+ r1.dump (dump_file);
+ fprintf (dump_file, ", range2 = ");
+ r1.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+
+ // Now solve for SSA1 or SSA2 if they are in the dependency chain.
+ if (ssa1 && in_chain_p (ssa1, cond_name))
+ {
+ if (compute_operand_range (tmp, def_stmt, cond_true, ssa1, src))
+ r1.intersect (tmp);
+ }
+ if (ssa2 && in_chain_p (ssa2, cond_name))
+ {
+ if (compute_operand_range (tmp, def_stmt, cond_false, ssa2, src))
+ r2.intersect (tmp);
+ }
+ if (idx)
+ {
+ tracer.print (idx, "outgoing: range1 = ");
+ r1.dump (dump_file);
+ fprintf (dump_file, ", range2 = ");
+ r1.dump (dump_file);
+ fprintf (dump_file, "\n");
+ tracer.trailer (idx, "cond_expr", true, cond_name, cond_true);
+ }
+ return true;
+}
+
// Dump what is known to GORI computes to listing file F.
void
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index b799a84..605884e 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -158,6 +158,8 @@ class gori_compute : public gori_map
public:
gori_compute (int not_executable_flag = 0);
bool outgoing_edge_range_p (irange &r, edge e, tree name, range_query &q);
+ bool condexpr_adjust (irange &r1, irange &r2, gimple *s, tree cond, tree op1,
+ tree op2, fur_source &src);
bool has_edge_range_p (tree name, basic_block bb = NULL);
bool has_edge_range_p (tree name, edge e);
void dump (FILE *f);
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 7d8850e..f570daa 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -250,6 +250,7 @@ static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
static hash_map<tree, tree> *oacc_declare_returns;
static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
bool (*) (tree), fallback_t, bool);
+static void prepare_gimple_addressable (tree *, gimple_seq *);
/* Shorter alias name for the above function for use in gimplify.cc
only. */
@@ -3122,10 +3123,12 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimplified before gimplifying the size expressions.
So we do this in three steps. First we deal with variable
- bounds, sizes, and positions, then we gimplify the base,
- then we deal with the annotations for any variables in the
- components and any indices, from left to right. */
+ bounds, sizes, and positions, then we gimplify the base and
+ ensure it is memory if needed, then we deal with the annotations
+ for any variables in the components and any indices, from left
+ to right. */
+ bool need_non_reg = false;
for (i = expr_stack.length () - 1; i >= 0; i--)
{
tree t = expr_stack[i];
@@ -3161,6 +3164,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
TREE_OPERAND (t, 3) = elmt_size;
}
}
+ need_non_reg = true;
}
else if (TREE_CODE (t) == COMPONENT_REF)
{
@@ -3182,6 +3186,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
TREE_OPERAND (t, 2) = offset;
}
}
+ need_non_reg = true;
}
}
@@ -3192,6 +3197,12 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
fallback | fb_lvalue);
ret = MIN (ret, tret);
+ /* Step 2a: if we have component references we do not support on
+ registers then make sure the base isn't a register. Of course
+ we can only do so if an rvalue is OK. */
+ if (need_non_reg && (fallback & fb_rvalue))
+ prepare_gimple_addressable (p, pre_p);
+
/* Step 3: gimplify size expressions and the indices and operands of
ARRAY_REF. During this loop we also remove any useless conversions. */
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index dd94ab3..f50a60b7 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,10 @@
+2022-02-13 Ian Lance Taylor <iant@golang.org>
+
+ * gospec.cc: Revert 2022-02-09 change:
+ (RTLIB, RT_LIBRARY): Don't define.
+ (lang_specific_driver): Don't add -lrt if linking statically
+ on GNU/Linux.
+
2022-02-09 Ian Lance Taylor <iant@golang.org>
* gospec.cc (RTLIB, RT_LIBRARY): Define.
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 745132a..3742414 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-0af68c0552341a44f1fb12301f9eff954b9dde88
+3742e8a154bfec805054b4ebf0809f12dc7694da
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 0652084..77176ef 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -191,6 +191,7 @@ static int target_nesting_level;
static bitmap task_shared_vars;
static bitmap global_nonaddressable_vars;
static vec<omp_context *> taskreg_contexts;
+static vec<gomp_task *> task_cpyfns;
static void scan_omp (gimple_seq *, omp_context *);
static tree scan_omp_1_op (tree *, int *, void *);
@@ -1082,9 +1083,6 @@ delete_omp_context (splay_tree_value value)
DECL_ABSTRACT_ORIGIN (t) = NULL;
}
- if (is_task_ctx (ctx))
- finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));
-
if (ctx->task_reduction_map)
{
ctx->task_reductions.release ();
@@ -11951,6 +11949,7 @@ create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
size_t looptempno = 0;
child_fn = gimple_omp_task_copy_fn (task_stmt);
+ task_cpyfns.safe_push (task_stmt);
child_cfun = DECL_STRUCT_FUNCTION (child_fn);
gcc_assert (child_cfun->cfg == NULL);
DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
@@ -14475,6 +14474,10 @@ execute_lower_omp (void)
&& (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl)))
== POINTER_TYPE))
remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl));
+
+ for (auto task_stmt : task_cpyfns)
+ finalize_task_copyfn (task_stmt);
+ task_cpyfns.release ();
return 0;
}
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index bd176e8..85ad990 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -7302,7 +7302,7 @@ simplify_immed_subreg (fixed_size_mode outermode, rtx x,
else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
return NULL_RTX;
rtx ret = native_decode_rtx (outermode, buffer, 0);
- if (ret && MODE_COMPOSITE_P (outermode))
+ if (ret && FLOAT_MODE_P (outermode))
{
auto_vec<target_unit, 128> buffer2 (buffer_bytes);
if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d50556d..5230f00 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,155 @@
+2022-02-15 Peter Bergner <bergner@linux.ibm.com>
+
+ * gcc.target/powerpc/htm-1.c: Retry intermittent failing tbegins.
+
+2022-02-15 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/104526
+ * gcc.dg/pr104526.c: New.
+
+2022-02-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/104524
+ * gcc.dg/analyzer/pr104524.c: New test.
+
+2022-02-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/102692
+ * gcc.dg/analyzer/pr102692-2.c: New test.
+ * gcc.dg/analyzer/pr102692.c: Remove xfail. Remove -O2 from
+ options and move to...
+ * gcc.dg/analyzer/torture/pr102692.c: ...here.
+
+2022-02-15 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/depend-4.f90: Add VALUE test, update scan test.
+ * gfortran.dg/gomp/depend-5.f90: Fix scan tree for -m32.
+ * gfortran.dg/gomp/depend-6.f90: New test.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/max_plus_1.c: New test.
+ * gcc.target/aarch64/max_plus_2.c: Likewise.
+ * gcc.target/aarch64/max_plus_3.c: Likewise.
+ * gcc.target/aarch64/max_plus_4.c: Likewise.
+ * gcc.target/aarch64/max_plus_5.c: Likewise.
+ * gcc.target/aarch64/max_plus_6.c: Likewise.
+ * gcc.target/aarch64/max_plus_7.c: Likewise.
+ * gcc.target/aarch64/min_plus_1.c: Likewise.
+ * gcc.target/aarch64/min_plus_2.c: Likewise.
+ * gcc.target/aarch64/min_plus_3.c: Likewise.
+ * gcc.target/aarch64/min_plus_4.c: Likewise.
+ * gcc.target/aarch64/min_plus_5.c: Likewise.
+ * gcc.target/aarch64/min_plus_6.c: Likewise.
+ * gcc.target/aarch64/min_plus_7.c: Likewise.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/store_v2vec_lanes.c: Add -fno-tree-vectorize.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/shl-combine-2.c: New test.
+ * gcc.target/aarch64/shl-combine-3.c: Likewise.
+ * gcc.target/aarch64/shl-combine-4.c: Likewise.
+ * gcc.target/aarch64/shl-combine-5.c: Likewise.
+ * gcc.target/aarch64/xtn-combine-1.c: Likewise.
+ * gcc.target/aarch64/xtn-combine-2.c: Likewise.
+ * gcc.target/aarch64/xtn-combine-3.c: Likewise.
+ * gcc.target/aarch64/xtn-combine-4.c: Likewise.
+ * gcc.target/aarch64/xtn-combine-5.c: Likewise.
+ * gcc.target/aarch64/xtn-combine-6.c: Likewise.
+
+2022-02-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/ldp_stp_5.c: Require -mstrict-align.
+ * gcc.target/aarch64/ldp_stp_14.h,
+ * gcc.target/aarch64/ldp_stp_14.c: New test.
+ * gcc.target/aarch64/ldp_stp_15.c: Likewise.
+ * gcc.target/aarch64/ldp_stp_16.c: Likewise.
+ * gcc.target/aarch64/ldp_stp_17.c: Likewise.
+ * gcc.target/aarch64/ldp_stp_18.c: Likewise.
+ * gcc.target/aarch64/ldp_stp_19.c: Likewise.
+
+2022-02-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104543
+ * gcc.dg/torture/pr104543.c: New testcase.
+
+2022-02-15 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/depend-4.f90: New test.
+ * gfortran.dg/gomp/depend-5.f90: New test.
+
+2022-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/104522
+ * gcc.dg/pr104522.c: New test.
+
+2022-02-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104519
+ * gcc.dg/torture/pr104519.c: New testcase.
+
+2022-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/104517
+ * gcc.dg/gomp/pr104517.c: New test.
+
+2022-02-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/104107
+ PR c++/95036
+ * g++.dg/cpp0x/alias-decl-ttp2.C: New test.
+ * g++.dg/cpp1z/ttp2.C: New test.
+
+2022-02-14 Michael Meissner <meissner@the-meissners.org>
+
+ PR target/104253
+ * gcc.target/powerpc/pr104253.c: New test.
+
+2022-02-14 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/104211
+ * gfortran.dg/pr104211.f90: New test.
+
+2022-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/104513
+ * g++.dg/cpp1y/constexpr-104513.C: New test.
+ * g++.dg/cpp2a/constexpr-dtor12.C: New test.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104528
+ * gfortran.dg/pr104528.f: New testcase.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/104511
+ * gcc.dg/pr104511.c: New testcase.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR c/104505
+ * c-c++-common/pr104505.c: New testcase.
+
+2022-02-14 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/104497
+ * c-c++-common/torture/pr104497.c: New testcase.
+
+2022-02-13 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/104228
+ * gfortran.dg/asan/associate_58.f90: New test.
+ * gfortran.dg/asan/associate_59.f90: New test.
+
+2022-02-13 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr103771-2.c: New test.
+ * gcc.target/i386/pr103771-3.c: New test.
+
2022-02-12 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/104449
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-31.c b/gcc/testsuite/c-c++-common/gomp/atomic-31.c
new file mode 100644
index 0000000..9ec3140
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-31.c
@@ -0,0 +1,11 @@
+/* c/104531 */
+/* { dg-do compile } */
+
+int x;
+
+void
+foo (_Complex int y)
+{
+ #pragma omp atomic compare /* { dg-error "invalid operands" } */
+ x = x > y ? y : x;
+}
diff --git a/gcc/testsuite/c-c++-common/pr104505.c b/gcc/testsuite/c-c++-common/pr104505.c
new file mode 100644
index 0000000..7fa3d84
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr104505.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+typedef char __attribute__((__vector_size__ (8))) U;
+typedef short __attribute__((__vector_size__ (16))) V;
+
+U u;
+
+void
+foo (V v)
+{
+ u = __builtin_shufflevector (u, u, __builtin_convertvector (v, U)); /* { dg-error "invalid element index" } */
+}
diff --git a/gcc/testsuite/c-c++-common/torture/pr104497.c b/gcc/testsuite/c-c++-common/torture/pr104497.c
new file mode 100644
index 0000000..c63fc02
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/pr104497.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+typedef int __attribute__((vector_size(16))) vec_t;
+
+vec_t src, inv, res;
+
+void test(int i)
+{
+ vec_t y={0};
+ y[i] = (i & 1 ? inv : src)[i];
+ res = y;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp2.C
new file mode 100644
index 0000000..230b277
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-ttp2.C
@@ -0,0 +1,25 @@
+// PR c++/104107
+// { dg-do compile { target c++11 } }
+
+template<int targ_id, typename t_parameter,
+ template<typename T, const T&> class tt_w_data>
+struct tt_main {
+ static t_parameter m_parameter;
+ template<template<typename T, const T&> class t_data>
+ using t_make = t_data<t_parameter, m_parameter>;
+ using t_data = t_make<tt_w_data>;
+};
+
+template<int targ_id, typename t_parameter,
+ template<typename T, const T&> class tt_w_data>
+t_parameter tt_main<targ_id, t_parameter, tt_w_data>::m_parameter;
+
+template<typename T, const T&> struct P {};
+struct t_parameter {};
+
+using toto = tt_main<0, t_parameter, P>;
+
+int main() {
+ toto t;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C
new file mode 100644
index 0000000..4fa78a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C
@@ -0,0 +1,10 @@
+// PR c++/104513
+// { dg-do compile { target c++14 } }
+
+struct A {
+ int a1;
+ short a2, a3;
+ long a4;
+ constexpr A() : a1(42), a2(42), a3(42), a4(42) { return; }
+};
+constexpr A a;
diff --git a/gcc/testsuite/g++.dg/cpp1z/ttp2.C b/gcc/testsuite/g++.dg/cpp1z/ttp2.C
new file mode 100644
index 0000000..1f161e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/ttp2.C
@@ -0,0 +1,21 @@
+// PR c++/95036
+// { dg-do compile { target c++17 } }
+
+namespace a {
+template <int b> struct c { static constexpr int d = b; };
+template <bool, typename e = void> using f = e;
+template <typename e, e...> struct g;
+template <typename> struct array;
+} // namespace a
+template <template <class> class h> struct i {
+ template <template <class, auto...> class, class = void> struct n;
+ template <class j> struct n<h, j> : a::c<true> {};
+ template <template <class> class k, class = a::f<n<k>::d>> void function();
+};
+template <template <class> class... l> struct derived : i<l>... {
+ using i<l>::function...;
+};
+int main() {
+ derived<a::array, a::g> m;
+ m.function<a::array>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C
new file mode 100644
index 0000000..19f9099b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C
@@ -0,0 +1,13 @@
+// PR c++/104513
+// { dg-do compile { target c++20 } }
+
+struct S {
+ constexpr S () : s (nullptr) {}
+ constexpr ~S () { delete s; }
+ int *s;
+};
+struct T : S {
+ constexpr T () : S () {}
+ constexpr ~T () { s = new int (42); return; }
+};
+constexpr T t;
diff --git a/gcc/testsuite/g++.dg/template/non-dependent21.C b/gcc/testsuite/g++.dg/template/non-dependent21.C
new file mode 100644
index 0000000..89900837
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent21.C
@@ -0,0 +1,9 @@
+// PR c++/104507
+
+extern const char *_k_errmsg[];
+
+template<class>
+const char* DoFoo(int __r, int __s) {
+ const char* n = _k_errmsg[(bool)__r && __s ? 1 : 2];
+ return n;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr102692-2.c b/gcc/testsuite/gcc.dg/analyzer/pr102692-2.c
new file mode 100644
index 0000000..c72fde2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr102692-2.c
@@ -0,0 +1,22 @@
+/* { dg-additional-options "-O1" } */
+
+struct Lisp_Overlay
+{
+ struct Lisp_Overlay *next;
+};
+
+void
+test_1 (struct Lisp_Overlay *tail, long prev)
+{
+ long end;
+ if (!tail || end < prev || !tail->next) /* { dg-warning "use of uninitialized value 'end'" } */
+ return;
+}
+
+void
+test_2 (struct Lisp_Overlay *tail, long prev)
+{
+ long end;
+ if (tail && end < prev && !tail->next) /* { dg-warning "use of uninitialized value 'end'" } */
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104524.c b/gcc/testsuite/gcc.dg/analyzer/pr104524.c
new file mode 100644
index 0000000..875098c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104524.c
@@ -0,0 +1,9 @@
+int src[1];
+
+int
+main (int c, char **a)
+{
+ __builtin_memcpy (*a, src, c);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr102692.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr102692.c
index c8993c8..a6c6bc4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr102692.c
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr102692.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-O2 -Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
/* TODO: remove the need for -Wno-analyzer-too-complex. */
struct lisp;
@@ -73,7 +73,7 @@ fix_overlays_before (struct buffer *bp, long prev, long pos)
parent = tail;
tail = tail->next;
}
- if (!tail || end < prev || !tail->next) /* { dg-bogus "use of uninitialized value 'end'" "uninit" { xfail *-*-* } } */
+ if (!tail || end < prev || !tail->next) /* { dg-bogus "use of uninitialized value 'end'" "uninit" } */
/* { dg-bogus "dereference of NULL 'tail'" "null deref" { target *-*-* } .-1 } */
return;
right_pair = parent;
diff --git a/gcc/testsuite/gcc.dg/dfp/pr104510.c b/gcc/testsuite/gcc.dg/dfp/pr104510.c
new file mode 100644
index 0000000..85f4e97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/pr104510.c
@@ -0,0 +1,12 @@
+/* PR c/104510 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+float f;
+_Decimal64 d;
+
+int
+foo (void)
+{
+ return d > (_Decimal32) (_Decimal64) f;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr104517.c b/gcc/testsuite/gcc.dg/gomp/pr104517.c
new file mode 100644
index 0000000..efb3175
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr104517.c
@@ -0,0 +1,54 @@
+/* PR debug/104517 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fcompare-debug -fopenmp -fno-tree-ter -save-temps" } */
+
+enum {
+ omp_default_mem_alloc,
+ omp_large_cap_mem_alloc,
+ omp_const_mem_alloc,
+ omp_high_bw_mem_alloc
+} omp_allocator_handle_t;
+
+int t, bar_nte, bar_tl, bar_i3, bar_dd;
+
+#pragma omp threadprivate(t)
+#pragma omp declare target
+int f, l, ll, r, r2;
+#pragma omp end declare target
+
+void
+bar (int *idp, int s, int nth, int g, int nta, int fi, int pp, int *q,
+ int ntm)
+{
+ int p = 0, i2 = 0, i1 = 0, m = 0, d = 0;
+
+#pragma omp target parallel for \
+ device(p) firstprivate (f) allocate (f) in_reduction(+:r2)
+ for (int i = 0; i < 4; i++)
+ ll++;
+
+#pragma omp target parallel for \
+ device(d) map (m) \
+ if (target: p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+ if (parallel: i2) reduction(+:r) num_threads (nth) linear (ll) \
+ schedule(static) collapse(1) nowait depend(inout: d) allocate (f) \
+ in_reduction(+:r2)
+ for (int i = 0; i < 4; i++)
+ ll++;
+
+#pragma omp taskloop simd firstprivate(f) lastprivate(s) grainsize(g) \
+ collapse(1) untied if (i1) final(fi) mergeable nogroup \
+ priority(pp) linear(ll) aligned(q) allocate(f)
+ for (int i = 0; i < 4; i++)
+ ll++;
+
+#pragma omp taskloop simd firstprivate(f) lastprivate(s) num_tasks(nta) \
+ collapse(1) if (i1) final(fi) priority(pp) safelen(8) simdlen(4) \
+ linear(ll) aligned(q) nontemporal(ntm) order(concurrent) allocate(f)
+ for (int i = 0; i < 4; i++)
+ ll++;
+
+#pragma omp parallel master firstprivate(f) shared(nth) proc_bind(spread) \
+ copyin(t) allocate(f)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr104511.c b/gcc/testsuite/gcc.dg/pr104511.c
new file mode 100644
index 0000000..ad5430c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104511.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target dfp } } */
+/* { dg-options "-O -Wno-psabi" } */
+
+typedef _Float64 __attribute__((__vector_size__ (32))) F;
+typedef _Decimal32 __attribute__((__vector_size__ (16))) D;
+
+extern void bar (void);
+
+D g;
+void
+foo (F f)
+{
+ D d = __builtin_convertvector (f, D);
+ bar ();
+ g = d;
+}
diff --git a/gcc/testsuite/gcc.dg/pr104522.c b/gcc/testsuite/gcc.dg/pr104522.c
new file mode 100644
index 0000000..4d1d630
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104522.c
@@ -0,0 +1,14 @@
+/* PR middle-end/104522 */
+/* { dg-do compile } */
+/* { dg-options "-O -fcompare-debug -dP" } */
+
+typedef short __attribute__((__vector_size__(16))) V;
+long double x;
+
+void
+foo (void)
+{
+ V t = { 512, 0, 0, 0, 16384 };
+ long double u = *(long double *) &t;
+ x /= u;
+}
diff --git a/gcc/testsuite/gcc.dg/pr104526.c b/gcc/testsuite/gcc.dg/pr104526.c
new file mode 100644
index 0000000..a295308
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104526.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo(void);
+
+static int a, b = 1, *c = &b;
+int main() {
+ for (; a; a--) {
+ int d = 2 >> (1 / *c);
+ if (!d)
+ foo();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr104544.c b/gcc/testsuite/gcc.dg/pr104544.c
new file mode 100644
index 0000000..275b666
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr104544.c
@@ -0,0 +1,19 @@
+/* PR rtl-optimization/104544 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+int m, n;
+__int128 q;
+
+void
+bar (unsigned __int128 x, int y)
+{
+ if (x)
+ q += y;
+}
+
+void
+foo (void)
+{
+ bar (!!q - 1, (m += m ? m : 1) < n);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr104519.c b/gcc/testsuite/gcc.dg/torture/pr104519.c
new file mode 100644
index 0000000..389c7bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr104519.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+signed char a, b;
+int main()
+{
+ for (b = -7; b; b += 3)
+ if (a)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr104543.c b/gcc/testsuite/gcc.dg/torture/pr104543.c
new file mode 100644
index 0000000..4896351
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr104543.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-additional-options "-floop-unroll-and-jam" } */
+
+int a[3], b, c;
+static int e()
+{
+ if (!c) {
+ for (b = 0; b < 3; b++)
+ for (c = 0; c < 3; c++)
+ a[c] ^= 1;
+ return -1;
+ }
+ return 0;
+}
+int main()
+{
+ e();
+ if (a[1] != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/atomic-inst-cas.c b/gcc/testsuite/gcc.target/aarch64/atomic-inst-cas.c
index f6f2892..0b4533a 100644
--- a/gcc/testsuite/gcc.target/aarch64/atomic-inst-cas.c
+++ b/gcc/testsuite/gcc.target/aarch64/atomic-inst-cas.c
@@ -1,5 +1,7 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -march=armv8-a+lse" } */
+/* -Winvalid-memory-model warnings are issued before the dead invalid calls
+ are removed. */
+/* { dg-options "-O2 -march=armv8-a+lse -Wno-invalid-memory-model" } */
/* Test ARMv8.1-A CAS instruction. */
diff --git a/gcc/testsuite/gcc.target/aarch64/bic-bitmask-1.c b/gcc/testsuite/gcc.target/aarch64/bic-bitmask-1.c
index 568c1ff..bcb9cdd 100644
--- a/gcc/testsuite/gcc.target/aarch64/bic-bitmask-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/bic-bitmask-1.c
@@ -10,4 +10,4 @@ uint32x4_t foo (int32x4_t a)
return vceqq_s32 (vbicq_s32 (a, cst), zero);
}
-/* { dg-final { scan-assembler-not {\tbic\t} { xfail { aarch64*-*-* } } } } */
+/* { dg-final { scan-assembler-not {\tbic\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_14.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_14.c
new file mode 100644
index 0000000..c7b5f7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_14.c
@@ -0,0 +1,89 @@
+/* { dg-options "-O2 -fno-tree-loop-distribute-patterns" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#include "ldp_stp_14.h"
+
+/*
+** const_2_int16_t_0:
+** str wzr, \[x0\]
+** ret
+*/
+CONST_FN (2, int16_t, 0);
+
+/*
+** const_4_int16_t_0:
+** str xzr, \[x0\]
+** ret
+*/
+CONST_FN (4, int16_t, 0);
+
+/*
+** const_8_int16_t_0:
+** stp xzr, xzr, \[x0\]
+** ret
+*/
+CONST_FN (8, int16_t, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (16, int16_t, 0);
+
+/*
+** const_32_int16_t_0:
+** movi v([0-9]+)\.4s, .*
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONST_FN (32, int16_t, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (2, int16_t, 1);
+
+/*
+** const_4_int16_t_1:
+** movi v([0-9]+)\.4h, .*
+** str d\1, \[x0\]
+** ret
+*/
+CONST_FN (4, int16_t, 1);
+
+/*
+** const_8_int16_t_1:
+** movi v([0-9]+)\.8h, .*
+** str q\1, \[x0\]
+** ret
+*/
+CONST_FN (8, int16_t, 1);
+
+/* Fuzzy match due to PR104387. */
+/*
+** dup_2_int16_t:
+** ...
+** strh w1, \[x0, #?2\]
+** ret
+*/
+DUP_FN (2, int16_t);
+
+/*
+** dup_4_int16_t:
+** dup v([0-9]+)\.4h, w1
+** str d\1, \[x0\]
+** ret
+*/
+DUP_FN (4, int16_t);
+
+/*
+** dup_8_int16_t:
+** dup v([0-9]+)\.8h, w1
+** str q\1, \[x0\]
+** ret
+*/
+DUP_FN (8, int16_t);
+
+/*
+** cons2_1_int16_t:
+** strh w1, \[x0\]
+** strh w2, \[x0, #?2\]
+** ret
+*/
+CONS2_FN (1, int16_t);
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_14.h b/gcc/testsuite/gcc.target/aarch64/ldp_stp_14.h
new file mode 100644
index 0000000..39c463f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_14.h
@@ -0,0 +1,50 @@
+#include <stdint.h>
+
+#define PRAGMA(X) _Pragma (#X)
+#define UNROLL(COUNT) PRAGMA (GCC unroll (COUNT))
+
+#define CONST_FN(COUNT, TYPE, VAL) \
+ void \
+ const_##COUNT##_##TYPE##_##VAL (TYPE *x) \
+ { \
+ UNROLL (COUNT) \
+ for (int i = 0; i < COUNT; ++i) \
+ x[i] = VAL; \
+ }
+
+#define DUP_FN(COUNT, TYPE) \
+ void \
+ dup_##COUNT##_##TYPE (TYPE *x, TYPE val) \
+ { \
+ UNROLL (COUNT) \
+ for (int i = 0; i < COUNT; ++i) \
+ x[i] = val; \
+ }
+
+#define CONS2_FN(COUNT, TYPE) \
+ void \
+ cons2_##COUNT##_##TYPE (TYPE *x, TYPE val0, TYPE val1) \
+ { \
+ UNROLL (COUNT) \
+ for (int i = 0; i < COUNT * 2; i += 2) \
+ { \
+ x[i + 0] = val0; \
+ x[i + 1] = val1; \
+ } \
+ }
+
+#define CONS4_FN(COUNT, TYPE) \
+ void \
+ cons4_##COUNT##_##TYPE (TYPE *x, TYPE val0, TYPE val1, \
+ TYPE val2, TYPE val3) \
+ { \
+ UNROLL (COUNT) \
+ for (int i = 0; i < COUNT * 4; i += 4) \
+ { \
+ x[i + 0] = val0; \
+ x[i + 1] = val1; \
+ x[i + 2] = val2; \
+ x[i + 3] = val3; \
+ } \
+ }
+
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_15.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_15.c
new file mode 100644
index 0000000..131cd0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_15.c
@@ -0,0 +1,137 @@
+/* { dg-options "-O2 -fno-tree-loop-distribute-patterns" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#include "ldp_stp_14.h"
+
+/*
+** const_2_int32_t_0:
+** str xzr, \[x0\]
+** ret
+*/
+CONST_FN (2, int32_t, 0);
+
+/*
+** const_4_int32_t_0:
+** stp xzr, xzr, \[x0\]
+** ret
+*/
+CONST_FN (4, int32_t, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (8, int32_t, 0);
+
+/*
+** const_16_int32_t_0:
+** movi v([0-9]+)\.4s, .*
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONST_FN (16, int32_t, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (2, int32_t, 1);
+
+/*
+** const_4_int32_t_1:
+** movi v([0-9]+)\.4s, .*
+** str q\1, \[x0\]
+** ret
+*/
+CONST_FN (4, int32_t, 1);
+
+/*
+** const_8_int32_t_1:
+** movi v([0-9]+)\.4s, .*
+** stp q\1, q\1, \[x0\]
+** ret
+*/
+CONST_FN (8, int32_t, 1);
+
+/*
+** dup_2_int32_t:
+** stp w1, w1, \[x0\]
+** ret
+*/
+DUP_FN (2, int32_t);
+
+/*
+** dup_4_int32_t:
+** stp w1, w1, \[x0\]
+** stp w1, w1, \[x0, #?8\]
+** ret
+*/
+DUP_FN (4, int32_t);
+
+/*
+** dup_8_int32_t:
+** dup v([0-9]+)\.4s, w1
+** stp q\1, q\1, \[x0\]
+** ret
+*/
+DUP_FN (8, int32_t);
+
+/*
+** cons2_1_int32_t:
+** stp w1, w2, \[x0\]
+** ret
+*/
+CONS2_FN (1, int32_t);
+
+/*
+** cons2_2_int32_t:
+** stp w1, w2, \[x0\]
+** stp w1, w2, \[x0, #?8\]
+** ret
+*/
+CONS2_FN (2, int32_t);
+
+/*
+** cons2_4_int32_t:
+** stp w1, w2, \[x0\]
+** stp w1, w2, \[x0, #?8\]
+** stp w1, w2, \[x0, #?16\]
+** stp w1, w2, \[x0, #?24\]
+** ret
+*/
+CONS2_FN (4, int32_t);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONS2_FN (8, int32_t);
+
+/*
+** cons2_16_int32_t:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS2_FN (16, int32_t);
+
+/*
+** cons4_1_int32_t:
+** stp w1, w2, \[x0\]
+** stp w3, w4, \[x0, #?8\]
+** ret
+*/
+CONS4_FN (1, int32_t);
+
+/*
+** cons4_2_int32_t:
+** stp w1, w2, \[x0\]
+** stp w3, w4, \[x0, #?8\]
+** stp w1, w2, \[x0, #?16\]
+** stp w3, w4, \[x0, #?24\]
+** ret
+*/
+CONS4_FN (2, int32_t);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONS4_FN (4, int32_t);
+
+/*
+** cons4_8_int32_t:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS4_FN (8, int32_t);
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_16.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_16.c
new file mode 100644
index 0000000..8ab117c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_16.c
@@ -0,0 +1,133 @@
+/* { dg-options "-O2 -fno-tree-loop-distribute-patterns" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#include "ldp_stp_14.h"
+
+/*
+** const_2_float_0:
+** str xzr, \[x0\]
+** ret
+*/
+CONST_FN (2, float, 0);
+
+/*
+** const_4_float_0:
+** stp xzr, xzr, \[x0\]
+** ret
+*/
+CONST_FN (4, float, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (8, float, 0);
+
+/*
+** const_16_float_0:
+** movi v([0-9]+)\.4s, .*
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONST_FN (16, float, 0);
+
+/*
+** const_2_float_1:
+** fmov v([0-9]+)\.2s, .*
+** str d\1, \[x0\]
+** ret
+*/
+CONST_FN (2, float, 1);
+
+/*
+** const_4_float_1:
+** fmov v([0-9]+)\.4s, .*
+** str q\1, \[x0\]
+** ret
+*/
+CONST_FN (4, float, 1);
+
+/*
+** dup_2_float:
+** stp s0, s0, \[x0\]
+** ret
+*/
+DUP_FN (2, float);
+
+/* No preference between vectorizing or not vectorizing here. */
+DUP_FN (4, float);
+
+/*
+** dup_8_float:
+** dup v([0-9]+)\.4s, v0.s\[0\]
+** stp q\1, q\1, \[x0\]
+** ret
+*/
+DUP_FN (8, float);
+
+/*
+** cons2_1_float:
+** stp s0, s1, \[x0\]
+** ret
+*/
+CONS2_FN (1, float);
+
+/*
+** cons2_2_float:
+** stp s0, s1, \[x0\]
+** stp s0, s1, \[x0, #?8\]
+** ret
+*/
+CONS2_FN (2, float);
+
+/*
+** cons2_4_float: { target aarch64_little_endian }
+** ins v0.s\[1\], v1.s\[0\]
+** stp d0, d0, \[x0\]
+** stp d0, d0, \[x0, #?16\]
+** ret
+*/
+/*
+** cons2_4_float: { target aarch64_big_endian }
+** ins v1.s\[1\], v0.s\[0\]
+** stp d1, d1, \[x0\]
+** stp d1, d1, \[x0, #?16\]
+** ret
+*/
+CONS2_FN (4, float);
+
+/*
+** cons2_8_float:
+** dup v([0-9]+)\.4s, .*
+** ...
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONS2_FN (8, float);
+
+/*
+** cons4_1_float:
+** stp s0, s1, \[x0\]
+** stp s2, s3, \[x0, #?8\]
+** ret
+*/
+CONS4_FN (1, float);
+
+/*
+** cons4_2_float:
+** stp s0, s1, \[x0\]
+** stp s2, s3, \[x0, #?8\]
+** stp s0, s1, \[x0, #?16\]
+** stp s2, s3, \[x0, #?24\]
+** ret
+*/
+CONS4_FN (2, float);
+
+/*
+** cons4_4_float:
+** ins v([0-9]+)\.s.*
+** ...
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONS4_FN (4, float);
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_17.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_17.c
new file mode 100644
index 0000000..c1122fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_17.c
@@ -0,0 +1,120 @@
+/* { dg-options "-O2 -fno-tree-loop-distribute-patterns" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#include "ldp_stp_14.h"
+
+/*
+** const_2_int64_t_0:
+** stp xzr, xzr, \[x0\]
+** ret
+*/
+CONST_FN (2, int64_t, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (4, int64_t, 0);
+
+/*
+** const_8_int64_t_0:
+** movi v([0-9]+)\.4s, .*
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONST_FN (8, int64_t, 0);
+
+/*
+** dup_2_int64_t:
+** stp x1, x1, \[x0\]
+** ret
+*/
+DUP_FN (2, int64_t);
+
+/*
+** dup_4_int64_t:
+** stp x1, x1, \[x0\]
+** stp x1, x1, \[x0, #?16\]
+** ret
+*/
+DUP_FN (4, int64_t);
+
+/* No preference between vectorizing or not vectorizing here. */
+DUP_FN (8, int64_t);
+
+/*
+** dup_16_int64_t:
+** dup v([0-9])\.2d, x1
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** stp q\1, q\1, \[x0, #?64\]
+** stp q\1, q\1, \[x0, #?96\]
+** ret
+*/
+DUP_FN (16, int64_t);
+
+/*
+** cons2_1_int64_t:
+** stp x1, x2, \[x0\]
+** ret
+*/
+CONS2_FN (1, int64_t);
+
+/*
+** cons2_2_int64_t:
+** stp x1, x2, \[x0\]
+** stp x1, x2, \[x0, #?16\]
+** ret
+*/
+CONS2_FN (2, int64_t);
+
+/*
+** cons2_4_int64_t:
+** stp x1, x2, \[x0\]
+** stp x1, x2, \[x0, #?16\]
+** stp x1, x2, \[x0, #?32\]
+** stp x1, x2, \[x0, #?48\]
+** ret
+*/
+CONS2_FN (4, int64_t);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONS2_FN (8, int64_t);
+
+/*
+** cons2_16_int64_t:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS2_FN (16, int64_t);
+
+/*
+** cons4_1_int64_t:
+** stp x1, x2, \[x0\]
+** stp x3, x4, \[x0, #?16\]
+** ret
+*/
+CONS4_FN (1, int64_t);
+
+/*
+** cons4_2_int64_t:
+** stp x1, x2, \[x0\]
+** stp x3, x4, \[x0, #?16\]
+** stp x1, x2, \[x0, #?32\]
+** stp x3, x4, \[x0, #?48\]
+** ret
+*/
+CONS4_FN (2, int64_t);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONS4_FN (4, int64_t);
+
+/* We should probably vectorize this, but currently don't. */
+CONS4_FN (8, int64_t);
+
+/*
+** cons4_16_int64_t:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS4_FN (16, int64_t);
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_18.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_18.c
new file mode 100644
index 0000000..eaa855c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_18.c
@@ -0,0 +1,123 @@
+/* { dg-options "-O2 -fno-tree-loop-distribute-patterns" } */
+/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
+
+#include "ldp_stp_14.h"
+
+/*
+** const_2_double_0:
+** stp xzr, xzr, \[x0\]
+** ret
+*/
+CONST_FN (2, double, 0);
+
+/* No preference between vectorizing or not vectorizing here. */
+CONST_FN (4, double, 0);
+
+/*
+** const_8_double_0:
+** movi v([0-9]+)\.2d, .*
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+CONST_FN (8, double, 0);
+
+/*
+** dup_2_double:
+** stp d0, d0, \[x0\]
+** ret
+*/
+DUP_FN (2, double);
+
+/*
+** dup_4_double:
+** stp d0, d0, \[x0\]
+** stp d0, d0, \[x0, #?16\]
+** ret
+*/
+DUP_FN (4, double);
+
+/*
+** dup_8_double:
+** dup v([0-9])\.2d, v0\.d\[0\]
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** ret
+*/
+DUP_FN (8, double);
+
+/*
+** dup_16_double:
+** dup v([0-9])\.2d, v0\.d\[0\]
+** stp q\1, q\1, \[x0\]
+** stp q\1, q\1, \[x0, #?32\]
+** stp q\1, q\1, \[x0, #?64\]
+** stp q\1, q\1, \[x0, #?96\]
+** ret
+*/
+DUP_FN (16, double);
+
+/*
+** cons2_1_double:
+** stp d0, d1, \[x0\]
+** ret
+*/
+CONS2_FN (1, double);
+
+/*
+** cons2_2_double:
+** stp d0, d1, \[x0\]
+** stp d0, d1, \[x0, #?16\]
+** ret
+*/
+CONS2_FN (2, double);
+
+/*
+** cons2_4_double:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS2_FN (4, double);
+
+/*
+** cons2_8_double:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS2_FN (8, double);
+
+/*
+** cons4_1_double:
+** stp d0, d1, \[x0\]
+** stp d2, d3, \[x0, #?16\]
+** ret
+*/
+CONS4_FN (1, double);
+
+/*
+** cons4_2_double:
+** stp d0, d1, \[x0\]
+** stp d2, d3, \[x0, #?16\]
+** stp d0, d1, \[x0, #?32\]
+** stp d2, d3, \[x0, #?48\]
+** ret
+*/
+CONS4_FN (2, double);
+
+/*
+** cons2_8_double:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS4_FN (4, double);
+
+/*
+** cons2_8_double:
+** ...
+** stp q[0-9]+, .*
+** ret
+*/
+CONS4_FN (8, double);
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_19.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_19.c
new file mode 100644
index 0000000..9eb4163
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_19.c
@@ -0,0 +1,6 @@
+/* { dg-options "-O2 -mstrict-align" } */
+
+#include "ldp_stp_5.c"
+
+/* { dg-final { scan-assembler-times {stp\tq[0-9]+, q[0-9]} 3 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {str\tq[0-9]+} 1 { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_5.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_5.c
index 9426618..56d1d3c 100644
--- a/gcc/testsuite/gcc.target/aarch64/ldp_stp_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_5.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mstrict-align" } */
double arr[4][4];
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_1.c b/gcc/testsuite/gcc.target/aarch64/max_plus_1.c
new file mode 100644
index 0000000..ef336ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_1.c
@@ -0,0 +1,149 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** adds (w[0-9]+), w0, #4
+** csel w0, \1, wzr, g[te]
+** ret
+*/
+/*
+** f2:
+** adds (w[0-9]+), w0, #4
+** csel w0, \1, wzr, g[te]
+** ret
+*/
+/*
+** f3:
+** adds (w[0-9]+), w0, #5
+** csinc w0, \1, wzr, gt
+** ret
+*/
+/*
+** f4:
+** adds (w[0-9]+), w0, #3
+** csinv w0, \1, wzr, ge
+** ret
+*/
+
+#ifndef TYPE
+#define TYPE int32_t
+#define TYPE_MIN INT32_MIN
+#define TYPE_MAX INT32_MAX
+#define VALUE -4
+#endif
+
+#include <stdint.h>
+
+TYPE __attribute__((noipa))
+f1 (TYPE x)
+{
+ return (x > VALUE ? x - VALUE : 0);
+}
+
+TYPE __attribute__((noipa))
+f2 (TYPE x)
+{
+ return (x > VALUE ? x : VALUE) - VALUE;
+}
+
+TYPE __attribute__((noipa))
+f3 (TYPE x)
+{
+ return (x > VALUE ? x : VALUE) - (VALUE - 1);
+}
+
+TYPE __attribute__((noipa))
+f4 (TYPE x)
+{
+ return (x > VALUE ? x : VALUE) - (VALUE + 1);
+}
+
+TYPE __attribute__((noipa))
+f5 (TYPE x)
+{
+ return (x > VALUE ? x : VALUE) - (VALUE + 2);
+}
+
+TYPE __attribute__((noipa))
+f6 (TYPE x)
+{
+ return (x > VALUE ? x : VALUE) - (VALUE - 2);
+}
+
+int
+main (void)
+{
+ TYPE max_test = TYPE_MAX;
+ if (TYPE_MIN < 0 && VALUE < 0)
+ max_test += VALUE;
+
+ if (f1 (TYPE_MIN) != 0)
+ __builtin_abort ();
+ if (f1 (VALUE - 1) != 0)
+ __builtin_abort ();
+ if (f1 (VALUE) != 0)
+ __builtin_abort ();
+ if (f1 (VALUE + 1) != 1)
+ __builtin_abort ();
+ if (f1 (max_test) != max_test - VALUE)
+ __builtin_abort ();
+
+ if (f2 (TYPE_MIN) != 0)
+ __builtin_abort ();
+ if (f2 (VALUE - 1) != 0)
+ __builtin_abort ();
+ if (f2 (VALUE) != 0)
+ __builtin_abort ();
+ if (f2 (VALUE + 1) != 1)
+ __builtin_abort ();
+ if (f2 (max_test) != max_test - VALUE)
+ __builtin_abort ();
+
+ if (f3 (TYPE_MIN) != 1)
+ __builtin_abort ();
+ if (f3 (VALUE - 1) != 1)
+ __builtin_abort ();
+ if (f3 (VALUE) != 1)
+ __builtin_abort ();
+ if (f3 (VALUE + 1) != 2)
+ __builtin_abort ();
+ if (f3 (max_test - 1) != max_test - VALUE)
+ __builtin_abort ();
+
+ if (f4 (TYPE_MIN) != -1)
+ __builtin_abort ();
+ if (f4 (VALUE - 1) != -1)
+ __builtin_abort ();
+ if (f4 (VALUE) != -1)
+ __builtin_abort ();
+ if (f4 (VALUE + 1) != 0)
+ __builtin_abort ();
+ if (f4 (max_test) != max_test - VALUE - 1)
+ __builtin_abort ();
+
+ if (f5 (TYPE_MIN) != -2)
+ __builtin_abort ();
+ if (f5 (VALUE - 1) != -2)
+ __builtin_abort ();
+ if (f5 (VALUE) != -2)
+ __builtin_abort ();
+ if (f5 (VALUE + 1) != -1)
+ __builtin_abort ();
+ if (f5 (max_test) != max_test - VALUE - 2)
+ __builtin_abort ();
+
+ if (f6 (TYPE_MIN) != 2)
+ __builtin_abort ();
+ if (f6 (VALUE - 1) != 2)
+ __builtin_abort ();
+ if (f6 (VALUE) != 2)
+ __builtin_abort ();
+ if (f6 (VALUE + 1) != 3)
+ __builtin_abort ();
+ if (VALUE <= max_test - 2 && f6 (max_test - 2) != max_test - VALUE)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_2.c b/gcc/testsuite/gcc.target/aarch64/max_plus_2.c
new file mode 100644
index 0000000..a2a1295
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_2.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** adds (x[0-9]+), x0, #4094
+** csel x0, \1, xzr, g[te]
+** ret
+*/
+/*
+** f2:
+** adds (x[0-9]+), x0, #4094
+** csel x0, \1, xzr, g[te]
+** ret
+*/
+/*
+** f3:
+** adds (x[0-9]+), x0, #4095
+** csinc x0, \1, xzr, gt
+** ret
+*/
+/*
+** f4:
+** adds (x[0-9]+), x0, #4093
+** csinv x0, \1, xzr, ge
+** ret
+*/
+
+#define TYPE int64_t
+#define TYPE_MIN INT64_MIN
+#define TYPE_MAX INT64_MAX
+#define VALUE -4094
+
+#include "max_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_3.c b/gcc/testsuite/gcc.target/aarch64/max_plus_3.c
new file mode 100644
index 0000000..a9792ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_3.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** adds (w[0-9]+), w0, #4095
+** csel w0, \1, wzr, g[te]
+** ret
+*/
+/*
+** f2:
+** adds (w[0-9]+), w0, #4095
+** csel w0, \1, wzr, g[te]
+** ret
+*/
+/*
+** f3:
+** adds (w[0-9]+), w0, #4096
+** csinc w0, \1, wzr, gt
+** ret
+*/
+/*
+** f4:
+** adds (w[0-9]+), w0, #4094
+** csinv w0, \1, wzr, ge
+** ret
+*/
+
+#define TYPE int32_t
+#define TYPE_MIN INT32_MIN
+#define TYPE_MAX INT32_MAX
+#define VALUE -4095
+
+#include "max_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_4.c b/gcc/testsuite/gcc.target/aarch64/max_plus_4.c
new file mode 100644
index 0000000..5090fa1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_4.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** adds (x[0-9]+), x0, #4096
+** csel x0, \1, xzr, g[te]
+** ret
+*/
+/*
+** f2:
+** adds (x[0-9]+), x0, #4096
+** csel x0, \1, xzr, g[te]
+** ret
+*/
+/* f3 out of range */
+/*
+** f4:
+** adds (x[0-9]+), x0, #4095
+** csinv x0, \1, xzr, ge
+** ret
+*/
+
+#define TYPE int64_t
+#define TYPE_MIN INT64_MIN
+#define TYPE_MAX INT64_MAX
+#define VALUE -4096
+
+#include "max_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_5.c b/gcc/testsuite/gcc.target/aarch64/max_plus_5.c
new file mode 100644
index 0000000..63f3b34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_5.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** adds (w[0-9]+), w0, #4095
+** csel w0, \1, wzr, (cs|hi)
+** ret
+*/
+/*
+** f2:
+** adds (w[0-9]+), w0, #4095
+** csel w0, \1, wzr, (cs|hi)
+** ret
+*/
+/*
+** f3:
+** adds (w[0-9]+), w0, #4096
+** csinc w0, \1, wzr, hi
+** ret
+*/
+/*
+** f4:
+** adds (w[0-9]+), w0, #4094
+** csinv w0, \1, wzr, cs
+** ret
+*/
+
+#define TYPE uint32_t
+#define TYPE_MIN 0
+#define TYPE_MAX UINT32_MAX
+#define VALUE (uint32_t)-4095
+
+#include "max_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_6.c b/gcc/testsuite/gcc.target/aarch64/max_plus_6.c
new file mode 100644
index 0000000..ad592c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_6.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#define TYPE uint64_t
+#define TYPE_MIN 0
+#define TYPE_MAX UINT64_MAX
+#define VALUE (uint64_t)-2
+
+#include "max_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/max_plus_7.c b/gcc/testsuite/gcc.target/aarch64/max_plus_7.c
new file mode 100644
index 0000000..ac9f27d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/max_plus_7.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** adds (x[0-9]+), x0, #3
+** csel x0, \1, xzr, (cs|hi)
+** ret
+*/
+/*
+** f2:
+** adds (x[0-9]+), x0, #3
+** csel x0, \1, xzr, (cs|hi)
+** ret
+*/
+/*
+** f3:
+** adds (x[0-9]+), x0, #4
+** csinc x0, \1, xzr, hi
+** ret
+*/
+/*
+** f4:
+** adds (x[0-9]+), x0, #2
+** csinv x0, \1, xzr, cs
+** ret
+*/
+
+#define TYPE uint64_t
+#define TYPE_MIN 0
+#define TYPE_MAX UINT64_MAX
+#define VALUE (uint64_t)-3
+
+#include "max_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_1.c b/gcc/testsuite/gcc.target/aarch64/min_plus_1.c
new file mode 100644
index 0000000..f4c9106
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_1.c
@@ -0,0 +1,149 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** subs (w[0-9]+), w0, #?4
+** csel w0, \1, wzr, l[te]
+** ret
+*/
+/*
+** f2:
+** subs (w[0-9]+), w0, #?4
+** csel w0, \1, wzr, l[te]
+** ret
+*/
+/*
+** f3:
+** subs (w[0-9]+), w0, #?3
+** csinc w0, \1, wzr, le
+** ret
+*/
+/*
+** f4:
+** subs (w[0-9]+), w0, #?5
+** csinv w0, \1, wzr, lt
+** ret
+*/
+
+#ifndef TYPE
+#define TYPE int32_t
+#define TYPE_MIN INT32_MIN
+#define TYPE_MAX INT32_MAX
+#define VALUE 4
+#endif
+
+#include <stdint.h>
+
+TYPE __attribute__((noipa))
+f1 (TYPE x)
+{
+ return (x < VALUE ? x - VALUE : 0);
+}
+
+TYPE __attribute__((noipa))
+f2 (TYPE x)
+{
+ return (x < VALUE ? x : VALUE) - VALUE;
+}
+
+TYPE __attribute__((noipa))
+f3 (TYPE x)
+{
+ return (x < VALUE ? x : VALUE) - (VALUE - 1);
+}
+
+TYPE __attribute__((noipa))
+f4 (TYPE x)
+{
+ return (x < VALUE ? x : VALUE) - (VALUE + 1);
+}
+
+TYPE __attribute__((noipa))
+f5 (TYPE x)
+{
+ return (x < VALUE ? x : VALUE) - (VALUE + 2);
+}
+
+TYPE __attribute__((noipa))
+f6 (TYPE x)
+{
+ return (x < VALUE ? x : VALUE) - (VALUE - 2);
+}
+
+int
+main (void)
+{
+ TYPE min_test = TYPE_MIN;
+ if (TYPE_MIN < 0 && VALUE > 0)
+ min_test += VALUE;
+
+ if (f1 (min_test) != min_test - VALUE)
+ __builtin_abort ();
+ if (f1 (VALUE - 1) != -1)
+ __builtin_abort ();
+ if (f1 (VALUE) != 0)
+ __builtin_abort ();
+ if (f1 (VALUE + 1) != 0)
+ __builtin_abort ();
+ if (f1 (TYPE_MAX) != 0)
+ __builtin_abort ();
+
+ if (f2 (min_test) != min_test - VALUE)
+ __builtin_abort ();
+ if (f2 (VALUE - 1) != -1)
+ __builtin_abort ();
+ if (f2 (VALUE) != 0)
+ __builtin_abort ();
+ if (f2 (VALUE + 1) != 0)
+ __builtin_abort ();
+ if (f2 (TYPE_MAX) != 0)
+ __builtin_abort ();
+
+ if (f3 (min_test) != min_test - VALUE + 1)
+ __builtin_abort ();
+ if (f3 (VALUE - 1) != 0)
+ __builtin_abort ();
+ if (f3 (VALUE) != 1)
+ __builtin_abort ();
+ if (f3 (VALUE + 1) != 1)
+ __builtin_abort ();
+ if (f3 (TYPE_MAX) != 1)
+ __builtin_abort ();
+
+ if (f4 (min_test + 1) != min_test - VALUE)
+ __builtin_abort ();
+ if (f4 (VALUE - 1) != -2)
+ __builtin_abort ();
+ if (f4 (VALUE) != -1)
+ __builtin_abort ();
+ if (f4 (VALUE + 1) != -1)
+ __builtin_abort ();
+ if (f4 (TYPE_MAX) != -1)
+ __builtin_abort ();
+
+ if (VALUE >= min_test + 2 && f5 (min_test + 2) != min_test - VALUE)
+ __builtin_abort ();
+ if (f5 (VALUE - 1) != -3)
+ __builtin_abort ();
+ if (f5 (VALUE) != -2)
+ __builtin_abort ();
+ if (f5 (VALUE + 1) != -2)
+ __builtin_abort ();
+ if (f5 (TYPE_MAX) != -2)
+ __builtin_abort ();
+
+ if (f6 (min_test) != min_test - VALUE + 2)
+ __builtin_abort ();
+ if (f6 (VALUE - 1) != 1)
+ __builtin_abort ();
+ if (f6 (VALUE) != 2)
+ __builtin_abort ();
+ if (f6 (VALUE + 1) != 2)
+ __builtin_abort ();
+ if (f6 (TYPE_MAX) != 2)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_2.c b/gcc/testsuite/gcc.target/aarch64/min_plus_2.c
new file mode 100644
index 0000000..bc0141b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_2.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** subs (x[0-9]+), x0, #?4094
+** csel x0, \1, xzr, l[te]
+** ret
+*/
+/*
+** f2:
+** subs (x[0-9]+), x0, #?4094
+** csel x0, \1, xzr, l[te]
+** ret
+*/
+/*
+** f3:
+** subs (x[0-9]+), x0, #?4093
+** csinc x0, \1, xzr, le
+** ret
+*/
+/*
+** f4:
+** subs (x[0-9]+), x0, #?4095
+** csinv x0, \1, xzr, lt
+** ret
+*/
+
+#define TYPE int64_t
+#define TYPE_MIN INT64_MIN
+#define TYPE_MAX INT64_MAX
+#define VALUE 4094
+
+#include "min_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_3.c b/gcc/testsuite/gcc.target/aarch64/min_plus_3.c
new file mode 100644
index 0000000..1808e4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_3.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** subs (w[0-9]+), w0, #?4095
+** csel w0, \1, wzr, l[te]
+** ret
+*/
+/*
+** f2:
+** subs (w[0-9]+), w0, #?4095
+** csel w0, \1, wzr, l[te]
+** ret
+*/
+/*
+** f3:
+** subs (w[0-9]+), w0, #?4094
+** csinc w0, \1, wzr, le
+** ret
+*/
+/*
+** f4:
+** subs (w[0-9]+), w0, #?4096
+** csinv w0, \1, wzr, lt
+** ret
+*/
+
+#define TYPE int32_t
+#define TYPE_MIN INT32_MIN
+#define TYPE_MAX INT32_MAX
+#define VALUE 4095
+
+#include "min_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_4.c b/gcc/testsuite/gcc.target/aarch64/min_plus_4.c
new file mode 100644
index 0000000..6c581fed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_4.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** subs (x[0-9]+), x0, #?4096
+** csel x0, \1, xzr, l[te]
+** ret
+*/
+/*
+** f2:
+** subs (x[0-9]+), x0, #?4096
+** csel x0, \1, xzr, l[te]
+** ret
+*/
+/*
+** f3:
+** subs (x[0-9]+), x0, #?4095
+** csinc x0, \1, xzr, le
+** ret
+*/
+/* f4 out of range */
+
+#define TYPE int64_t
+#define TYPE_MIN INT64_MIN
+#define TYPE_MAX INT64_MAX
+#define VALUE 4096
+
+#include "min_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_5.c b/gcc/testsuite/gcc.target/aarch64/min_plus_5.c
new file mode 100644
index 0000000..97542d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_5.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** subs (w[0-9]+), w0, #?4095
+** csel w0, \1, wzr, (cc|ls)
+** ret
+*/
+/*
+** f2:
+** subs (w[0-9]+), w0, #?4095
+** csel w0, \1, wzr, (cc|ls)
+** ret
+*/
+/*
+** f3:
+** subs (w[0-9]+), w0, #?4094
+** csinc w0, \1, wzr, ls
+** ret
+*/
+/*
+** f4:
+** subs (w[0-9]+), w0, #?4096
+** csinv w0, \1, wzr, cc
+** ret
+*/
+
+#define TYPE uint32_t
+#define TYPE_MIN 0
+#define TYPE_MAX UINT32_MAX
+#define VALUE 4095
+
+#include "min_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_6.c b/gcc/testsuite/gcc.target/aarch64/min_plus_6.c
new file mode 100644
index 0000000..176533c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_6.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#define TYPE uint64_t
+#define TYPE_MIN 0
+#define TYPE_MAX UINT64_MAX
+#define VALUE 1
+
+#include "min_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/min_plus_7.c b/gcc/testsuite/gcc.target/aarch64/min_plus_7.c
new file mode 100644
index 0000000..d6a217a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/min_plus_7.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+** f1:
+** subs (x[0-9]+), x0, #?2
+** csel x0, \1, xzr, (cc|ls)
+** ret
+*/
+/*
+** f2:
+** subs (x[0-9]+), x0, #?2
+** csel x0, \1, xzr, (cc|ls)
+** ret
+*/
+/*
+** f3:
+** subs (x[0-9]+), x0, #?1
+** csinc x0, \1, xzr, ls
+** ret
+*/
+/*
+** f4:
+** subs (x[0-9]+), x0, #?3
+** csinv x0, \1, xzr, cc
+** ret
+*/
+
+#define TYPE uint64_t
+#define TYPE_MIN 0
+#define TYPE_MAX UINT64_MAX
+#define VALUE 2
+
+#include "min_plus_1.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/pr100056.c b/gcc/testsuite/gcc.target/aarch64/pr100056.c
index 0b77824..70499772 100644
--- a/gcc/testsuite/gcc.target/aarch64/pr100056.c
+++ b/gcc/testsuite/gcc.target/aarch64/pr100056.c
@@ -1,7 +1,9 @@
/* PR target/100056 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-not {\t[us]bfiz\tw[0-9]+, w[0-9]+, 11} } } */
+/* { dg-final { scan-assembler-not {\t[us]bfiz\tw[0-9]+, w[0-9]+, 11} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {\t[us]bfiz\tw[0-9]+, w[0-9]+, 11} 2 } } */
+/* { dg-final { scan-assembler-times {\tadd\tw[0-9]+, w[0-9]+, w[0-9]+, uxtb\n} 2 } } */
int
or_shift_u8 (unsigned char i)
diff --git a/gcc/testsuite/gcc.target/aarch64/shl-combine-2.c b/gcc/testsuite/gcc.target/aarch64/shl-combine-2.c
index 6a0331f..491fd44 100644
--- a/gcc/testsuite/gcc.target/aarch64/shl-combine-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/shl-combine-2.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define TYPE char
void e (signed TYPE * restrict a, signed TYPE *b, int n)
diff --git a/gcc/testsuite/gcc.target/aarch64/shl-combine-3.c b/gcc/testsuite/gcc.target/aarch64/shl-combine-3.c
index 2086b24a..39bef21 100644
--- a/gcc/testsuite/gcc.target/aarch64/shl-combine-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/shl-combine-3.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define TYPE short
void e (signed TYPE * restrict a, signed TYPE *b, int n)
diff --git a/gcc/testsuite/gcc.target/aarch64/shl-combine-4.c b/gcc/testsuite/gcc.target/aarch64/shl-combine-4.c
index 0831810..15dcbff 100644
--- a/gcc/testsuite/gcc.target/aarch64/shl-combine-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/shl-combine-4.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define TYPE int
void e (signed TYPE * restrict a, signed TYPE *b, int n)
diff --git a/gcc/testsuite/gcc.target/aarch64/shl-combine-5.c b/gcc/testsuite/gcc.target/aarch64/shl-combine-5.c
index 6b2a6bd..703f630 100644
--- a/gcc/testsuite/gcc.target/aarch64/shl-combine-5.c
+++ b/gcc/testsuite/gcc.target/aarch64/shl-combine-5.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define TYPE long
void e (signed TYPE * restrict a, signed TYPE *b, int n)
diff --git a/gcc/testsuite/gcc.target/aarch64/store_v2vec_lanes.c b/gcc/testsuite/gcc.target/aarch64/store_v2vec_lanes.c
index 3296d04..7ea8a67 100644
--- a/gcc/testsuite/gcc.target/aarch64/store_v2vec_lanes.c
+++ b/gcc/testsuite/gcc.target/aarch64/store_v2vec_lanes.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-tree-vectorize" } */
typedef long long v2di __attribute__ ((vector_size (16)));
typedef double v2df __attribute__ ((vector_size (16)));
diff --git a/gcc/testsuite/gcc.target/aarch64/xtn-combine-1.c b/gcc/testsuite/gcc.target/aarch64/xtn-combine-1.c
index 14e0414..27b7858 100644
--- a/gcc/testsuite/gcc.target/aarch64/xtn-combine-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/xtn-combine-1.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define SIGN signed
#define TYPE1 char
#define TYPE2 short
diff --git a/gcc/testsuite/gcc.target/aarch64/xtn-combine-2.c b/gcc/testsuite/gcc.target/aarch64/xtn-combine-2.c
index c259010..02f03fa 100644
--- a/gcc/testsuite/gcc.target/aarch64/xtn-combine-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/xtn-combine-2.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define SIGN signed
#define TYPE1 short
#define TYPE2 int
diff --git a/gcc/testsuite/gcc.target/aarch64/xtn-combine-3.c b/gcc/testsuite/gcc.target/aarch64/xtn-combine-3.c
index 9a2065f..4bcbd85 100644
--- a/gcc/testsuite/gcc.target/aarch64/xtn-combine-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/xtn-combine-3.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define SIGN signed
#define TYPE1 int
#define TYPE2 long long
diff --git a/gcc/testsuite/gcc.target/aarch64/xtn-combine-4.c b/gcc/testsuite/gcc.target/aarch64/xtn-combine-4.c
index 77c3dce..29703d1 100644
--- a/gcc/testsuite/gcc.target/aarch64/xtn-combine-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/xtn-combine-4.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define SIGN unsigned
#define TYPE1 char
#define TYPE2 short
diff --git a/gcc/testsuite/gcc.target/aarch64/xtn-combine-5.c b/gcc/testsuite/gcc.target/aarch64/xtn-combine-5.c
index ae30e86..f5ee30d 100644
--- a/gcc/testsuite/gcc.target/aarch64/xtn-combine-5.c
+++ b/gcc/testsuite/gcc.target/aarch64/xtn-combine-5.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define SIGN unsigned
#define TYPE1 short
#define TYPE2 int
diff --git a/gcc/testsuite/gcc.target/aarch64/xtn-combine-6.c b/gcc/testsuite/gcc.target/aarch64/xtn-combine-6.c
index 882f3d3..3ddb87e 100644
--- a/gcc/testsuite/gcc.target/aarch64/xtn-combine-6.c
+++ b/gcc/testsuite/gcc.target/aarch64/xtn-combine-6.c
@@ -1,6 +1,8 @@
/* { dg-do assemble } */
/* { dg-options "-O3 --save-temps --param=vect-epilogues-nomask=0" } */
+#pragma GCC target "+nosve"
+
#define SIGN unsigned
#define TYPE1 int
#define TYPE2 long long
diff --git a/gcc/testsuite/gcc.target/i386/pr104448.c b/gcc/testsuite/gcc.target/i386/pr104448.c
new file mode 100644
index 0000000..b10345a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104448.c
@@ -0,0 +1,9 @@
+/* PR target/104448 */
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-mavx5124vnniw -mno-xsave -mabi=ms" } */
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/htm-1.c b/gcc/testsuite/gcc.target/powerpc/htm-1.c
index f27e32c..399a7ec 100644
--- a/gcc/testsuite/gcc.target/powerpc/htm-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/htm-1.c
@@ -12,14 +12,21 @@ main (void)
{
long i;
unsigned long mask = 0;
+ unsigned long retry_count = 0;
repeat:
if (__builtin_tbegin (0))
{
mask++;
+ retry_count = 0;
}
else
- abort();
+ {
+ /* Retry a limited number of times before aborting. */
+ if (retry_count++ < 10)
+ goto repeat;
+ abort ();
+ }
if (mask == 1)
{
diff --git a/gcc/testsuite/gcc.target/powerpc/pr104253.c b/gcc/testsuite/gcc.target/powerpc/pr104253.c
new file mode 100644
index 0000000..02049cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr104253.c
@@ -0,0 +1,156 @@
+/*
+ * Require float128 support because __ibm128 currently is not enabled unless we
+ * also have __float128 support. We require software IEEE 128-bit support,
+ * which will work on power8. If we have hardware IEEE 128-bit support (power9
+ * or power10), ppc_float128_sw will still enable running the test.
+ */
+
+/* { dg-do run } */
+/* { require-effective-target ppc_float128_sw } */
+/* { dg-options "-O2 -mvsx -mfloat128" } */
+
+/*
+ * PR target/104253
+ *
+ * Verify that the various conversions to and from __ibm128 work. When the
+ * default for long double is changed to IEEE 128-bit, originally GCC would
+ * call the functions using an 'if' name instead of 'tf' name.
+ */
+
+#include <stdlib.h>
+
+extern float ibm128_to_sf (__ibm128) __attribute__((noinline));
+extern double ibm128_to_df (__ibm128) __attribute__((noinline));
+extern int ibm128_to_si (__ibm128) __attribute__((noinline));
+extern long long ibm128_to_di (__ibm128) __attribute__((noinline));
+extern unsigned int ibm128_to_usi (__ibm128) __attribute__((noinline));
+extern unsigned long long ibm128_to_udi (__ibm128) __attribute__((noinline));
+
+extern __ibm128 sf_to_ibm128 (float) __attribute__((noinline));
+extern __ibm128 df_to_ibm128 (double) __attribute__((noinline));
+extern __ibm128 si_to_ibm128 (int) __attribute__((noinline));
+extern __ibm128 di_to_ibm128 (long long) __attribute__((noinline));
+extern __ibm128 usi_to_ibm128 (unsigned int) __attribute__((noinline));
+extern __ibm128 udi_to_ibm128 (unsigned long long) __attribute__((noinline));
+
+float
+ibm128_to_sf (__ibm128 x)
+{
+ return x;
+}
+
+double
+ibm128_to_df (__ibm128 x)
+{
+ return x;
+}
+
+int
+ibm128_to_si (__ibm128 x)
+{
+ return x;
+}
+
+long long
+ibm128_to_di (__ibm128 x)
+{
+ return x;
+}
+
+unsigned int
+ibm128_to_usi (__ibm128 x)
+{
+ return x;
+}
+
+unsigned long long
+ibm128_to_udi (__ibm128 x)
+{
+ return x;
+}
+
+__ibm128
+sf_to_ibm128 (float x)
+{
+ return x;
+}
+
+__ibm128
+df_to_ibm128 (double x)
+{
+ return x;
+}
+
+__ibm128
+si_to_ibm128 (int x)
+{
+ return x;
+}
+
+__ibm128
+di_to_ibm128 (long long x)
+{
+ return x;
+}
+
+__ibm128
+usi_to_ibm128 (unsigned int x)
+{
+ return x;
+}
+
+__ibm128
+udi_to_ibm128 (unsigned long long x)
+{
+ return x;
+}
+
+volatile float seven_sf = 7.0f;
+volatile double seven_df = 7.0;
+volatile int seven_si = 7;
+volatile long long seven_di = 7LL;
+volatile unsigned int seven_usi = 7U;
+volatile unsigned long long seven_udi = 7ULL;
+volatile __ibm128 seven_ibm128 = 7.0;
+
+int
+main (void)
+{
+ if (seven_ibm128 != sf_to_ibm128 (seven_sf))
+ abort ();
+
+ if (seven_ibm128 != df_to_ibm128 (seven_df))
+ abort ();
+
+ if (seven_ibm128 != si_to_ibm128 (seven_si))
+ abort ();
+
+ if (seven_ibm128 != di_to_ibm128 (seven_di))
+ abort ();
+
+ if (seven_ibm128 != usi_to_ibm128 (seven_usi))
+ abort ();
+
+ if (seven_ibm128 != udi_to_ibm128 (seven_udi))
+ abort ();
+
+ if (seven_sf != ibm128_to_sf (seven_ibm128))
+ abort ();
+
+ if (seven_df != ibm128_to_df (seven_ibm128))
+ abort ();
+
+ if (seven_si != ibm128_to_si (seven_ibm128))
+ abort ();
+
+ if (seven_di != ibm128_to_di (seven_ibm128))
+ abort ();
+
+ if (seven_usi != ibm128_to_usi (seven_ibm128))
+ abort ();
+
+ if (seven_udi != ibm128_to_udi (seven_ibm128))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/casttuple.d b/gcc/testsuite/gdc.test/compilable/casttuple.d
new file mode 100644
index 0000000..c4c2bc8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/casttuple.d
@@ -0,0 +1,31 @@
+alias tuple(T...) = T;
+
+void exactMatch()
+{
+ tuple!int tup_1;
+
+ auto i = cast() tup_1;
+ static assert(is(typeof(i) == int));
+ const i_const = cast(const) tup_1;
+ static assert(is(typeof(i_const) == const int));
+
+ auto totup_1 = cast(tuple!int) tup_1;
+ static assert(is(typeof(totup_1) == tuple!int));
+
+ tuple!(int, int) tup_2;
+ auto totup_2 = cast(tuple!(int, int)) tup_2;
+ static assert(is(typeof(totup_2) == tuple!(int, int)));
+}
+
+void implicitConv()
+{
+ tuple!short tup_1;
+ auto totup_1 = cast(tuple!int) tup_1;
+ static assert(is(typeof(tup_1) == tuple!short));
+ static assert(is(typeof(totup_1) == tuple!int));
+
+ tuple!(short, short) tup_2;
+ auto totup_2 = cast(tuple!(int, int)) tup_2;
+ static assert(is(typeof(tup_2) == tuple!(short, short)));
+ static assert(is(typeof(totup_2) == tuple!(int, int)));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/deprecated_override.d b/gcc/testsuite/gdc.test/compilable/deprecated_override.d
new file mode 100644
index 0000000..c9da34d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/deprecated_override.d
@@ -0,0 +1,97 @@
+// https://issues.dlang.org/show_bug.cgi?id=22668
+
+// Overrides with same deprecated'ness are allowed
+
+class SameParent
+{
+ deprecated void foo() {}
+ void foo(int) {}
+
+ void bar(int) {}
+ deprecated void bar() {}
+}
+
+class SameChild : SameParent
+{
+ deprecated override void foo() {}
+ override void foo(int) {}
+
+ override void bar(int) {}
+ deprecated override void bar() {}
+}
+
+/**
+Only the parent declaration is deprecated
+
+TEST_OUTPUT:
+----
+compilable/deprecated_override.d(44): Deprecation: `deprecated_override.IntroducingChild.foo` is overriding the deprecated method `deprecated_override.IntroducingParent.foo`
+compilable/deprecated_override.d(48): Deprecation: `deprecated_override.IntroducingChild.bar` is overriding the deprecated method `deprecated_override.IntroducingParent.bar`
+----
+**/
+
+class IntroducingParent
+{
+ deprecated void foo() {}
+ void foo(int) {}
+
+ void bar(int) {}
+ deprecated void bar() {}
+}
+
+class IntroducingChild : IntroducingParent
+{
+ override void foo() {}
+ override void foo(int) {}
+
+ override void bar(int) {}
+ override void bar() {}
+}
+
+// Unrelated to this path but should this error as well?
+
+class IntroducingGrandchild : IntroducingChild
+{
+ override void foo() {}
+ override void foo(int) {}
+
+ override void bar(int) {}
+ override void bar() {}
+}
+
+/**
+Only the overriding declaration is deprecated
+
+TEST_OUTPUT:
+----
+compilable/deprecated_override.d(83): Deprecation: `deprecated_override.OverrideChild.foo` cannot be marked as `deprecated` because it is overriding a function in the base class
+compilable/deprecated_override.d(87): Deprecation: `deprecated_override.OverrideChild.bar` cannot be marked as `deprecated` because it is overriding a function in the base class
+----
+**/
+
+class OverrideParent
+{
+ void foo() {}
+ void foo(int) {}
+
+ void bar(int) {}
+ void bar() {}
+}
+
+class OverrideChild : OverrideParent
+{
+ deprecated override void foo() {}
+ override void foo(int) {}
+
+ override void bar(int) {}
+ deprecated override void bar() {}
+}
+
+class OverrideGrandChild : OverrideChild
+{
+ deprecated override void foo() {}
+ override void foo(int) {}
+
+ override void bar(int) {}
+ deprecated override void bar() {}
+}
diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/header1.d b/gcc/testsuite/gdc.test/compilable/extra-files/header1.d
index 209d4a0..01cf889 100644
--- a/gcc/testsuite/gdc.test/compilable/extra-files/header1.d
+++ b/gcc/testsuite/gdc.test/compilable/extra-files/header1.d
@@ -600,3 +600,9 @@ struct Test14UDA4(string v){}
void test14x(@Test14UDA1 int, @Test14UDA2("1") int, @test14uda3("2") int, @Test14UDA4!"3" int) {}
void test15x(@(20) void delegate(int) @safe dg){}
+
+T throwStuff(T)(T t)
+{
+ if (false) test13x(1, throw new Exception(""), 2);
+ return t ? t : throw new Exception("Bad stuff happens!");
+}
diff --git a/gcc/testsuite/gdc.test/compilable/fix17635.d b/gcc/testsuite/gdc.test/compilable/fix17635.d
new file mode 100644
index 0000000..dd14de1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/fix17635.d
@@ -0,0 +1,16 @@
+// https://issues.dlang.org/show_bug.cgi?id=17635
+
+alias T = immutable int;
+
+T** f(const T** input) pure
+{
+ T** output;
+ return output;
+}
+
+void main()
+{
+ T i;
+ T* p = &i;
+ immutable T** r = f(&p);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/fix22291.d b/gcc/testsuite/gdc.test/compilable/fix22291.d
new file mode 100644
index 0000000..4090c5e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/fix22291.d
@@ -0,0 +1,134 @@
+//https://issues.dlang.org/show_bug.cgi?id=22291
+
+alias AliasSeq(T...) = T;
+void noParameters()
+{
+ static assert(typeof(__traits(parameters)).length == 0);
+}
+void noArgs()
+{
+ //Arguments are not valid, this should not compile
+ static assert(!__traits(compiles, __traits(parameters, 456)));
+}
+shared static this()
+{
+ static assert(typeof(__traits(parameters)).length == 0);
+}
+int echoPlusOne(int x)
+{
+ __traits(parameters)[0] += 1;
+ return x;
+}
+static assert(echoPlusOne(1) == 2);
+class Tree {
+ int opApply(int delegate(size_t, Tree) dg) {
+ if (dg(0, this)) return 1;
+ return 0;
+ }
+}
+void useOpApply(Tree top, int x)
+{
+ foreach(idx; 0..5)
+ {
+ static assert(is(typeof(__traits(parameters)) == AliasSeq!(Tree, int)));
+ }
+ foreach(idx, elem; top)
+ {
+ static assert(is(typeof(__traits(parameters)) == AliasSeq!(size_t, Tree)));
+ }
+}
+class Test
+{
+ static assert(!__traits(compiles, __traits(parameters)));
+ void handle(int x)
+ {
+ static assert(typeof(__traits(parameters)).length == 1);
+ }
+}
+
+int add(int x, int y)
+{
+ return x + y;
+}
+
+auto forwardToAdd(int x, int y)
+{
+ return add(__traits(parameters));
+}
+static assert(forwardToAdd(2, 3) == 5);
+struct TestConstructor
+{
+ int x;
+ string y;
+ //This parameter will not have a name but it's (tuple) members
+ //will
+ this(typeof(this.tupleof))
+ {
+ this.tupleof = __traits(parameters);
+ }
+}
+bool test(int x, string y)
+{
+ auto s = TestConstructor(2, "pi");
+ return s.x == x && s.y == y;
+}
+static assert(test(2, "pi"));
+int testNested(int x)
+{
+ static assert(typeof(__traits(parameters)).length == 1);
+ int add(int x, int y)
+ {
+ static assert(typeof(__traits(parameters)).length == 2);
+ return x + y;
+ }
+ return add(x + 2, x + 3);
+}
+void testPack(Pack...)(Pack x)
+{
+ static assert(is(typeof(__traits(parameters)) == typeof(AliasSeq!(x))));
+}
+
+ref int forwardTest(return ref int x)
+{
+ static assert(__traits(isRef, x) == __traits(isRef, __traits(parameters)[0]));
+ return x;
+}
+
+int testRefness(int x, ref int monkey)
+{
+ {
+ //monkey = x;
+ __traits(parameters)[1] = __traits(parameters)[0];
+ }
+ return x;
+}
+int refTest()
+{
+ int x;
+ testRefness(45, x);
+ return x;
+}
+auto packLength(Pack...)(Pack x)
+{
+ return typeof(__traits(parameters)).length;
+}
+static assert(packLength(2, 3) == 2);
+alias lambda = (x) => typeof(__traits(parameters)).stringof;
+static assert(lambda(1) == "(int)");
+static assert(refTest() == 45);
+
+T testTemplate(T)(scope T input)
+{
+ void chimpInASuit(float set)
+ {
+ static assert(is(typeof(__traits(parameters)) == AliasSeq!(float)));
+ }
+ {
+ __traits(parameters) = AliasSeq!(T.max);
+ }
+ __traits(parameters) = AliasSeq!(T.init);
+ return input;
+}
+
+static assert(testTemplate!long(420) == 0);
+
diff --git a/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c b/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
new file mode 100644
index 0000000..f6aaf3b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
@@ -0,0 +1,6 @@
+// check bugs in importing C files
+
+int squared(int a)
+{
+ return a * a;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp22625.c b/gcc/testsuite/gdc.test/compilable/imports/imp22625.c
new file mode 100644
index 0000000..0d18459
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp22625.c
@@ -0,0 +1 @@
+typedef struct S { int x; } T;
diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp22665.c b/gcc/testsuite/gdc.test/compilable/imports/imp22665.c
new file mode 100644
index 0000000..f575cff
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/imp22665.c
@@ -0,0 +1 @@
+enum E { A };
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test22685b.d b/gcc/testsuite/gdc.test/compilable/imports/test22685b.d
new file mode 100644
index 0000000..e1854d1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test22685b.d
@@ -0,0 +1,5 @@
+module imports.test22685b;
+
+import imports.test22685c : overloaded;
+
+void overloaded()() { }
diff --git a/gcc/testsuite/gdc.test/compilable/imports/test22685c.d b/gcc/testsuite/gdc.test/compilable/imports/test22685c.d
new file mode 100644
index 0000000..e2c8ad1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/test22685c.d
@@ -0,0 +1,3 @@
+module imports.test22685c;
+
+void overloaded()() { }
diff --git a/gcc/testsuite/gdc.test/compilable/issue22130.d b/gcc/testsuite/gdc.test/compilable/issue22130.d
new file mode 100644
index 0000000..34a631d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue22130.d
@@ -0,0 +1,12 @@
+// https://issues.dlang.org/show_bug.cgi?id=22130
+
+int* f(const int* input) pure nothrow @safe
+{
+ int* output;
+ return output;
+}
+void main() pure nothrow @safe
+{
+ int* c = new int;
+ immutable int* i = f(c);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d
index 22734cf..5bba9ba 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d
@@ -20,8 +20,7 @@ static assert(!is(noreturn == void));
static assert(is( typeof(assert(0)) == noreturn ));
-// Does not parse yet
-// static assert(is( typeof(throw new Exception()) == noreturn ));
+static assert(is( typeof(throw new Exception("")) == noreturn ));
static assert(is(noreturn == noreturn));
static assert(!is(noreturn == const noreturn));
diff --git a/gcc/testsuite/gdc.test/compilable/test13008.d b/gcc/testsuite/gdc.test/compilable/test13008.d
index fd1f41d..f19fdb7 100644
--- a/gcc/testsuite/gdc.test/compilable/test13008.d
+++ b/gcc/testsuite/gdc.test/compilable/test13008.d
@@ -1,10 +1,6 @@
// REQUIRED_ARGS: -o-
// PERMUTE_ARGS: -d -de -dw
-/*
-TEST_OUTPUT*
----
----
-*/
+
deprecated class Dep { }
deprecated Dep depFunc1(); // error
deprecated void depFunc2(Dep); // error
diff --git a/gcc/testsuite/gdc.test/compilable/test18771.d b/gcc/testsuite/gdc.test/compilable/test18771.d
index a71361f..e6a511c 100644
--- a/gcc/testsuite/gdc.test/compilable/test18771.d
+++ b/gcc/testsuite/gdc.test/compilable/test18771.d
@@ -1,4 +1,4 @@
-// REQUIRED_ARGS : -c
+// REQUIRED_ARGS: -c
// EXTRA_FILES: imports/test18771a.d imports/test18771b.d imports/test18771c.d imports/test18771d.d
// https://issues.dlang.org/show_bug.cgi?id=18771
diff --git a/gcc/testsuite/gdc.test/compilable/test19609.d b/gcc/testsuite/gdc.test/compilable/test19609.d
index 2646bd4..4367df1 100644
--- a/gcc/testsuite/gdc.test/compilable/test19609.d
+++ b/gcc/testsuite/gdc.test/compilable/test19609.d
@@ -1,7 +1,7 @@
// https://issues.dlang.org/show_bug.cgi?id=19609
// EXTRA_FILES: imports/test19609a.d imports/test19609b.d imports/test19609c.d
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
compilable/test19609.d(11): Deprecation: module `imports.test19609a` is deprecated -
compilable/test19609.d(12): Deprecation: module `imports.test19609b` is deprecated - hello
diff --git a/gcc/testsuite/gdc.test/compilable/test19873.d b/gcc/testsuite/gdc.test/compilable/test19873.d
index 7252edd..e69b4df 100644
--- a/gcc/testsuite/gdc.test/compilable/test19873.d
+++ b/gcc/testsuite/gdc.test/compilable/test19873.d
@@ -1,4 +1,4 @@
-// PERMUTE_ARGS -preview=dip1000
+// PERMUTE_ARGS: -preview=dip1000
// https://issues.dlang.org/show_bug.cgi?id=19873
int* ed(scope int* x)
{
diff --git a/gcc/testsuite/gdc.test/compilable/test21299a.d b/gcc/testsuite/gdc.test/compilable/test21299a.d
index 3c6d8ec..12cc579 100644
--- a/gcc/testsuite/gdc.test/compilable/test21299a.d
+++ b/gcc/testsuite/gdc.test/compilable/test21299a.d
@@ -1,4 +1,4 @@
// EXTRA_SOURCES: imports/test21299/mtype.d imports/test21299/func.d imports/test21299/rootstringtable.d
// REQUIRED_ARGS: -main
-// LINK
+// LINK:
module test21299a;
diff --git a/gcc/testsuite/gdc.test/compilable/test22619.d b/gcc/testsuite/gdc.test/compilable/test22619.d
new file mode 100644
index 0000000..fd5e894
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22619.d
@@ -0,0 +1,11 @@
+// https://issues.dlang.org/show_bug.cgi?id=22619
+
+struct W1 {
+ int x;
+ this(ref inout W1 rhs) inout { this.x = rhs.x; }
+}
+
+inout(W1) f(inout W1 x) { return x; }
+void g(W1 x) {
+ auto r = f(x);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22625.d b/gcc/testsuite/gdc.test/compilable/test22625.d
new file mode 100644
index 0000000..adf6676
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22625.d
@@ -0,0 +1,4 @@
+// https://issues.dlang.org/show_bug.cgi?id=22625
+// EXTRA_FILES: imports/imp22625.c
+
+import imports.imp22625 : S, T;
diff --git a/gcc/testsuite/gdc.test/compilable/test22646.d b/gcc/testsuite/gdc.test/compilable/test22646.d
new file mode 100644
index 0000000..ae44d81
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22646.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=22646
+
+/*
+TEST_OUTPUT:
+---
+true
+true
+false
+false
+---
+*/
+
+static template Bug(string name)
+{
+ enum bool ok = name.length < 3 || name[0..3] != "pad";
+}
+
+pragma(msg, Bug!"x".ok);
+pragma(msg, Bug!"foo".ok);
+pragma(msg, Bug!"pad".ok);
+pragma(msg, Bug!"pad123".ok);
diff --git a/gcc/testsuite/gdc.test/compilable/test22665.d b/gcc/testsuite/gdc.test/compilable/test22665.d
new file mode 100644
index 0000000..9d55dbb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22665.d
@@ -0,0 +1,22 @@
+// EXTRA_FILES: imports/imp22665.c
+
+// https://issues.dlang.org/show_bug.cgi?id=22665
+
+import imports.imp22665;
+
+E foo1(E e)
+{
+ return e.A; // with qualification, it is an enum
+}
+
+int foo2()
+{
+ return A; // without qualification, it is an int
+}
+
+E foo3(E e)
+{
+ return E.A; // with qualification, it is an enum
+}
+
+
diff --git a/gcc/testsuite/gdc.test/compilable/test22676.d b/gcc/testsuite/gdc.test/compilable/test22676.d
new file mode 100644
index 0000000..8adc132
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22676.d
@@ -0,0 +1,25 @@
+// https://issues.dlang.org/show_bug.cgi?id=22676
+template fullyQualifiedName(T)
+{
+ static if (is(T : real))
+ enum fullyQualifiedName;
+
+ enum fullyQualifiedName = null;
+}
+
+static auto _inst()
+{
+ return fullyQualifiedName!(frop);
+}
+
+alias attr = __traits(getAttributes, _inst);
+
+class frop
+{
+ alias type_id = registry!frop;
+}
+
+template registry(T)
+{
+ enum string FOO = fullyQualifiedName!T;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22685.d b/gcc/testsuite/gdc.test/compilable/test22685.d
new file mode 100644
index 0000000..504cc9d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22685.d
@@ -0,0 +1,11 @@
+// EXTRA_FILES: imports/test22685b.d imports/test22685c.d
+
+module test22685;
+
+import imports.test22685b;
+
+void twoArgs(alias a, alias b)() { }
+
+void main() {
+ twoArgs!(a => 1, overloaded);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test55.d b/gcc/testsuite/gdc.test/compilable/test55.d
index 6dfc665..4b413e1 100644
--- a/gcc/testsuite/gdc.test/compilable/test55.d
+++ b/gcc/testsuite/gdc.test/compilable/test55.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// COMPILED_IMPORTS: imports/test55a.d
// PERMUTE_ARGS: -dw
// REQUIRED_ARGS: -d
@@ -17,4 +17,3 @@ class Queue2 {
alias int ListHead;
Arm2 a;
}
-
diff --git a/gcc/testsuite/gdc.test/compilable/testcstuff3.d b/gcc/testsuite/gdc.test/compilable/testcstuff3.d
new file mode 100644
index 0000000..89228a9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/testcstuff3.d
@@ -0,0 +1,4 @@
+// EXTRA_FILES: imports/cstuff3.c
+import imports.cstuff3;
+
+static assert(squared(4) == 16);
diff --git a/gcc/testsuite/gdc.test/compilable/testos.d b/gcc/testsuite/gdc.test/compilable/testos.d
new file mode 100644
index 0000000..e0eb3a5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/testos.d
@@ -0,0 +1,7 @@
+/* PERMUTE_ARGS: -os=host -os=linux -os=osx -os=freebsd -os=solaris
+ * DISABLED: win32 win64
+ */
+
+void test()
+{
+}
diff --git a/gcc/testsuite/gdc.test/compilable/b16967.d b/gcc/testsuite/gdc.test/fail_compilation/b16967.d
index 57bc1c1..7a2c3e4 100644
--- a/gcc/testsuite/gdc.test/compilable/b16967.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/b16967.d
@@ -1,9 +1,8 @@
/*
- * REQUIRED_ARGS: -c
* TEST_OUTPUT:
---
-compilable/b16967.d(16): Deprecation: switch case fallthrough - use 'goto default;' if intended
-compilable/b16967.d(26): Deprecation: switch case fallthrough - use 'goto default;' if intended
+fail_compilation/b16967.d(15): Error: switch case fallthrough - use 'goto default;' if intended
+fail_compilation/b16967.d(25): Error: switch case fallthrough - use 'goto default;' if intended
---
*/
int foo(int x)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug5096.d b/gcc/testsuite/gdc.test/fail_compilation/bug5096.d
new file mode 100644
index 0000000..2063e41
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/bug5096.d
@@ -0,0 +1,14 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/bug5096.d(13): Error: unmatched closing brace
+---
+*/
+void foo(int x)
+ in {
+ assert(x > 0);
+ } do {
+ x++;
+ }
+}
+void main() {}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
index 33ea0cd..0edd5e9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/bug9631.d
@@ -91,9 +91,9 @@ TEST_OUTPUT:
---
fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S _param_0)` is not callable using argument types `(S)`
fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S _param_0`
-fail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` cannot deduce function from argument types `!()(S)`
+fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)`
fail_compilation/bug9631.d(105): Candidate is: `ft()(tem!().S)`
-fail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` cannot deduce function from argument types `!()(S, int)`
+fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)`
fail_compilation/bug9631.d(108): Candidate is: `ft2(T)(S, T)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/casttuple.d b/gcc/testsuite/gdc.test/fail_compilation/casttuple.d
new file mode 100644
index 0000000..d08de08b5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/casttuple.d
@@ -0,0 +1,25 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/casttuple.d(104): Error: cannot cast `__tup1_field_0` of type `int` to tuple type `(string)`
+fail_compilation/casttuple.d(107): Error: cannot cast `tuple(__tup2_field_0, __tup2_field_1)` of type `(int, int)` to tuple type `(string, string)`
+fail_compilation/casttuple.d(111): Error: cannot cast `tuple(foo, 123)` of type `(int, int)` to tuple type `(string, string)`
+---
+ */
+
+alias tuple(T...) = T;
+
+#line 100
+
+void nomatch()
+{
+ tuple!int tup1;
+ auto x = cast(tuple!string) tup1;
+
+ tuple!(int, int) tup2;
+ auto y = cast(tuple!(string, string)) tup2;
+
+ int foo;
+ alias tup3 = tuple!(foo, 123);
+ auto z = cast(tuple!(string, string)) tup3;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d
index a60ea8c..9f12ae6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_aggr.d
@@ -2,12 +2,12 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
-fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_aggr.d(32): Error: none of the overloads of template `imports.constraints.C.f` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(60): Candidate is: `f(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
-fail_compilation/constraints_aggr.d(33): Error: template `imports.constraints.C.g` cannot deduce function from argument types `!()()`
+fail_compilation/constraints_aggr.d(33): Error: none of the overloads of template `imports.constraints.C.g` are callable using argument types `!()()`
fail_compilation/imports/constraints.d(63): Candidate is: `g(this T)()`
with `T = imports.constraints.C`
must satisfy the following constraint:
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d
index 91dd405..aac8760 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func1.d
@@ -2,72 +2,72 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
-fail_compilation/constraints_func1.d(79): Error: template `imports.constraints.test1` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(79): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func1.d(80): Error: template `imports.constraints.test2` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(80): Error: none of the overloads of template `imports.constraints.test2` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(10): Candidate is: `test2(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
-fail_compilation/constraints_func1.d(81): Error: template `imports.constraints.test3` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(81): Error: none of the overloads of template `imports.constraints.test3` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(11): Candidate is: `test3(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func1.d(82): Error: template `imports.constraints.test4` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(82): Error: none of the overloads of template `imports.constraints.test4` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(12): Candidate is: `test4(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func1.d(83): Error: template `imports.constraints.test5` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(83): Error: none of the overloads of template `imports.constraints.test5` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(13): Candidate is: `test5(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
-fail_compilation/constraints_func1.d(84): Error: template `imports.constraints.test6` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(84): Error: none of the overloads of template `imports.constraints.test6` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(14): Candidate is: `test6(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T
!P!T`
-fail_compilation/constraints_func1.d(85): Error: template `imports.constraints.test7` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(85): Error: none of the overloads of template `imports.constraints.test7` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(15): Candidate is: `test7(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
-fail_compilation/constraints_func1.d(86): Error: template `imports.constraints.test8` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(86): Error: none of the overloads of template `imports.constraints.test8` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(16): Candidate is: `test8(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func1.d(87): Error: template `imports.constraints.test9` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(87): Error: none of the overloads of template `imports.constraints.test9` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(17): Candidate is: `test9(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
-fail_compilation/constraints_func1.d(88): Error: template `imports.constraints.test10` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(88): Error: none of the overloads of template `imports.constraints.test10` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(18): Candidate is: `test10(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
-fail_compilation/constraints_func1.d(89): Error: template `imports.constraints.test11` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(89): Error: none of the overloads of template `imports.constraints.test11` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(19): Candidate is: `test11(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
!P!T`
-fail_compilation/constraints_func1.d(90): Error: template `imports.constraints.test12` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func1.d(90): Error: none of the overloads of template `imports.constraints.test12` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(20): Candidate is: `test12(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
-fail_compilation/constraints_func1.d(92): Error: template `imports.constraints.test1` cannot deduce function from argument types `!()(int, int)`
+fail_compilation/constraints_func1.d(92): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int, int)`
fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d
index 67aa78c..a20426d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func2.d
@@ -2,83 +2,83 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
-fail_compilation/constraints_func2.d(94): Error: template `imports.constraints.test13` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(94): Error: none of the overloads of template `imports.constraints.test13` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(23): Candidate is: `test13(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
!P!T`
-fail_compilation/constraints_func2.d(95): Error: template `imports.constraints.test14` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(95): Error: none of the overloads of template `imports.constraints.test14` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(24): Candidate is: `test14(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
N!T`
-fail_compilation/constraints_func2.d(96): Error: template `imports.constraints.test15` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(96): Error: none of the overloads of template `imports.constraints.test15` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(25): Candidate is: `test15(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
!P!T`
-fail_compilation/constraints_func2.d(97): Error: template `imports.constraints.test16` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(97): Error: none of the overloads of template `imports.constraints.test16` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(26): Candidate is: `test16(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
-fail_compilation/constraints_func2.d(98): Error: template `imports.constraints.test17` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(98): Error: none of the overloads of template `imports.constraints.test17` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(27): Candidate is: `test17(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func2.d(99): Error: template `imports.constraints.test18` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(99): Error: none of the overloads of template `imports.constraints.test18` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(28): Candidate is: `test18(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
-fail_compilation/constraints_func2.d(100): Error: template `imports.constraints.test19` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(100): Error: none of the overloads of template `imports.constraints.test19` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(29): Candidate is: `test19(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
!P!T
N!T`
-fail_compilation/constraints_func2.d(101): Error: template `imports.constraints.test20` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(101): Error: none of the overloads of template `imports.constraints.test20` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(30): Candidate is: `test20(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func2.d(102): Error: template `imports.constraints.test21` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(102): Error: none of the overloads of template `imports.constraints.test21` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(31): Candidate is: `test21(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
-fail_compilation/constraints_func2.d(103): Error: template `imports.constraints.test22` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(103): Error: none of the overloads of template `imports.constraints.test22` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(32): Candidate is: `test22(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
!P!T`
-fail_compilation/constraints_func2.d(104): Error: template `imports.constraints.test23` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(104): Error: none of the overloads of template `imports.constraints.test23` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(33): Candidate is: `test23(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
N!T
!P!T`
-fail_compilation/constraints_func2.d(105): Error: template `imports.constraints.test24` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(105): Error: none of the overloads of template `imports.constraints.test24` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(34): Candidate is: `test24(R)(R r)`
with `R = int`
must satisfy the following constraint:
` __traits(hasMember, R, "stuff")`
-fail_compilation/constraints_func2.d(106): Error: template `imports.constraints.test25` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func2.d(106): Error: none of the overloads of template `imports.constraints.test25` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(35): Candidate is: `test25(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
-fail_compilation/constraints_func2.d(107): Error: template `imports.constraints.test26` cannot deduce function from argument types `!(float)(int)`
+fail_compilation/constraints_func2.d(107): Error: none of the overloads of template `imports.constraints.test26` are callable using argument types `!(float)(int)`
fail_compilation/imports/constraints.d(36): Candidate is: `test26(T, U)(U u)`
with `T = float,
U = int`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d
index f0a5099..6f214b9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func3.d
@@ -2,7 +2,7 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
-fail_compilation/constraints_func3.d(53): Error: template `imports.constraints.overload` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func3.d(53): Error: none of the overloads of template `imports.constraints.overload` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(39): Candidates are: `overload(T)(T v)`
with `T = int`
must satisfy the following constraint:
@@ -13,7 +13,7 @@ fail_compilation/imports/constraints.d(40): `overload(T)(
` !P!T`
fail_compilation/imports/constraints.d(41): `overload(T)(T v1, T v2)`
fail_compilation/imports/constraints.d(42): `overload(T, V)(T v1, V v2)`
-fail_compilation/constraints_func3.d(54): Error: template `imports.constraints.overload` cannot deduce function from argument types `!()(int, string)`
+fail_compilation/constraints_func3.d(54): Error: none of the overloads of template `imports.constraints.overload` are callable using argument types `!()(int, string)`
fail_compilation/imports/constraints.d(39): Candidates are: `overload(T)(T v)`
fail_compilation/imports/constraints.d(40): `overload(T)(T v)`
fail_compilation/imports/constraints.d(41): `overload(T)(T v1, T v2)`
@@ -23,21 +23,21 @@ fail_compilation/imports/constraints.d(42): `overload(T,
must satisfy one of the following constraints:
` N!T
N!V`
-fail_compilation/constraints_func3.d(56): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()()`
+fail_compilation/constraints_func3.d(56): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
-fail_compilation/constraints_func3.d(57): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func3.d(57): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
with `A = int,
T = ()`
must satisfy the following constraint:
` N!int`
-fail_compilation/constraints_func3.d(58): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()(int, int)`
+fail_compilation/constraints_func3.d(58): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
with `A = int,
T = (int)`
must satisfy the following constraint:
` N!int`
-fail_compilation/constraints_func3.d(59): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()(int, int, int)`
+fail_compilation/constraints_func3.d(59): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
with `A = int,
T = (int, int)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d
index 751e618..4048bae 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/constraints_func4.d
@@ -3,7 +3,7 @@ EXTRA_FILES: imports/constraints.d
REQUIRED_ARGS: -verrors=context
TEST_OUTPUT:
---
-fail_compilation/constraints_func4.d(90): Error: template `imports.constraints.overload` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func4.d(90): Error: none of the overloads of template `imports.constraints.overload` are callable using argument types `!()(int)`
overload(0);
^
fail_compilation/imports/constraints.d(39): Candidates are: `overload(T)(T v)`
@@ -24,7 +24,7 @@ void overload(T)(T v1, T v2) if (N!T);
fail_compilation/imports/constraints.d(42): `overload(T, V)(T v1, V v2)`
void overload(T, V)(T v1, V v2) if (N!T || N!V);
^
-fail_compilation/constraints_func4.d(91): Error: template `imports.constraints.overload` cannot deduce function from argument types `!()(int, string)`
+fail_compilation/constraints_func4.d(91): Error: none of the overloads of template `imports.constraints.overload` are callable using argument types `!()(int, string)`
overload(0, "");
^
fail_compilation/imports/constraints.d(39): Candidates are: `overload(T)(T v)`
@@ -44,13 +44,13 @@ fail_compilation/imports/constraints.d(42): `overload(T,
N!V`
void overload(T, V)(T v1, V v2) if (N!T || N!V);
^
-fail_compilation/constraints_func4.d(93): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()()`
+fail_compilation/constraints_func4.d(93): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
variadic();
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
void variadic(A, T...)(A a, T v) if (N!int);
^
-fail_compilation/constraints_func4.d(94): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()(int)`
+fail_compilation/constraints_func4.d(94): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
variadic(0);
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
@@ -60,7 +60,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T.
` N!int`
void variadic(A, T...)(A a, T v) if (N!int);
^
-fail_compilation/constraints_func4.d(95): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()(int, int)`
+fail_compilation/constraints_func4.d(95): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
variadic(0, 1);
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
@@ -70,7 +70,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T.
` N!int`
void variadic(A, T...)(A a, T v) if (N!int);
^
-fail_compilation/constraints_func4.d(96): Error: template `imports.constraints.variadic` cannot deduce function from argument types `!()(int, int, int)`
+fail_compilation/constraints_func4.d(96): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
variadic(0, 1, 2);
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag11819b.d b/gcc/testsuite/gdc.test/fail_compilation/diag11819b.d
index a5d6a14..aa43727 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag11819b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag11819b.d
@@ -1,25 +1,24 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag11819b.d(28): Error: unrecognized trait `HasMember`, did you mean `hasMember`?
-fail_compilation/diag11819b.d(29): Error: unrecognized trait `Identifier`, did you mean `identifier`?
-fail_compilation/diag11819b.d(30): Error: unrecognized trait `GetProtection`, did you mean `getProtection`?
-fail_compilation/diag11819b.d(31): Error: unrecognized trait `Parent`, did you mean `parent`?
-fail_compilation/diag11819b.d(32): Error: unrecognized trait `GetMember`, did you mean `getMember`?
-fail_compilation/diag11819b.d(33): Error: unrecognized trait `GetOverloads`, did you mean `getOverloads`?
-fail_compilation/diag11819b.d(34): Error: unrecognized trait `GetVirtualFunctions`, did you mean `getVirtualFunctions`?
-fail_compilation/diag11819b.d(35): Error: unrecognized trait `GetVirtualMethods`, did you mean `getVirtualMethods`?
-fail_compilation/diag11819b.d(36): Error: unrecognized trait `ClassInstanceSize`, did you mean `classInstanceSize`?
-fail_compilation/diag11819b.d(37): Error: unrecognized trait `AllMembers`, did you mean `allMembers`?
-fail_compilation/diag11819b.d(38): Error: unrecognized trait `DerivedMembers`, did you mean `derivedMembers`?
-fail_compilation/diag11819b.d(39): Error: unrecognized trait `IsSame`, did you mean `isSame`?
-fail_compilation/diag11819b.d(40): Error: unrecognized trait `Compiles`, did you mean `compiles`?
-fail_compilation/diag11819b.d(41): Error: unrecognized trait `Parameters`
-fail_compilation/diag11819b.d(42): Error: unrecognized trait `GetAliasThis`, did you mean `getAliasThis`?
-fail_compilation/diag11819b.d(43): Error: unrecognized trait `GetAttributes`, did you mean `getAttributes`?
-fail_compilation/diag11819b.d(44): Error: unrecognized trait `GetFunctionAttributes`, did you mean `getFunctionAttributes`?
-fail_compilation/diag11819b.d(45): Error: unrecognized trait `GetUnitTests`, did you mean `getUnitTests`?
-fail_compilation/diag11819b.d(46): Error: unrecognized trait `GetVirtualIndex`, did you mean `getVirtualIndex`?
+fail_compilation/diag11819b.d(27): Error: unrecognized trait `HasMember`, did you mean `hasMember`?
+fail_compilation/diag11819b.d(28): Error: unrecognized trait `Identifier`, did you mean `identifier`?
+fail_compilation/diag11819b.d(29): Error: unrecognized trait `GetProtection`, did you mean `getProtection`?
+fail_compilation/diag11819b.d(30): Error: unrecognized trait `Parent`, did you mean `parent`?
+fail_compilation/diag11819b.d(31): Error: unrecognized trait `GetMember`, did you mean `getMember`?
+fail_compilation/diag11819b.d(32): Error: unrecognized trait `GetOverloads`, did you mean `getOverloads`?
+fail_compilation/diag11819b.d(33): Error: unrecognized trait `GetVirtualFunctions`, did you mean `getVirtualFunctions`?
+fail_compilation/diag11819b.d(34): Error: unrecognized trait `GetVirtualMethods`, did you mean `getVirtualMethods`?
+fail_compilation/diag11819b.d(35): Error: unrecognized trait `ClassInstanceSize`, did you mean `classInstanceSize`?
+fail_compilation/diag11819b.d(36): Error: unrecognized trait `AllMembers`, did you mean `allMembers`?
+fail_compilation/diag11819b.d(37): Error: unrecognized trait `DerivedMembers`, did you mean `derivedMembers`?
+fail_compilation/diag11819b.d(38): Error: unrecognized trait `IsSame`, did you mean `isSame`?
+fail_compilation/diag11819b.d(39): Error: unrecognized trait `Compiles`, did you mean `compiles`?
+fail_compilation/diag11819b.d(40): Error: unrecognized trait `GetAliasThis`, did you mean `getAliasThis`?
+fail_compilation/diag11819b.d(41): Error: unrecognized trait `GetAttributes`, did you mean `getAttributes`?
+fail_compilation/diag11819b.d(42): Error: unrecognized trait `GetFunctionAttributes`, did you mean `getFunctionAttributes`?
+fail_compilation/diag11819b.d(43): Error: unrecognized trait `GetUnitTests`, did you mean `getUnitTests`?
+fail_compilation/diag11819b.d(44): Error: unrecognized trait `GetVirtualIndex`, did you mean `getVirtualIndex`?
---
*/
@@ -38,7 +37,6 @@ void main()
if (__traits(DerivedMembers)) { }
if (__traits(IsSame)) { }
if (__traits(Compiles)) { }
- if (__traits(Parameters)) { }
if (__traits(GetAliasThis)) { }
if (__traits(GetAttributes)) { }
if (__traits(GetFunctionAttributes)) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13333.d b/gcc/testsuite/gdc.test/fail_compilation/diag13333.d
index 34eeaeb..88e8a9d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag13333.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag13333.d
@@ -1,5 +1,5 @@
/*
-TEST_OUTPUT*
+TEST_OUTPUT:
---
fail_compilation/diag13333.d(29): Error: template instance `VariantN!(maxSize!(S), T)` recursive template expansion
fail_compilation/diag13333.d(29): Error: template instance `diag13333.maxSize!(S)` error instantiating
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d
index 992d5b8..aeee107 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag13942.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag13942.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)`
-fail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` cannot deduce function from argument types `!()()`
+fail_compilation/diag13942.d(26): Error: none of the overloads of template `diag13942.to!double.to` are callable using argument types `!()()`
fail_compilation/diag13942.d(17): Candidate is: `to(A...)(A args)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16271.d b/gcc/testsuite/gdc.test/fail_compilation/diag16271.d
index b85dc8d..e209593 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag16271.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag16271.d
@@ -1,5 +1,5 @@
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/diag16271.d(10): Error: found `x` when expecting function literal following `ref`
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d
index 8f991a7..9d8dcfd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag16977.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag16977.d
@@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/diag16977.d(25): Error: undefined identifier `undefined`, did you mean function `undefinedId`?
fail_compilation/diag16977.d(26): Error: cannot implicitly convert expression `"\x01string"` of type `string` to `int`
-fail_compilation/diag16977.d(27): Error: template `diag16977.templ` cannot deduce function from argument types `!()(int)`
+fail_compilation/diag16977.d(27): Error: none of the overloads of template `diag16977.templ` are callable using argument types `!()(int)`
fail_compilation/diag16977.d(20): Candidate is: `templ(S)(S s)`
with `S = int`
must satisfy the following constraint:
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag19225.d b/gcc/testsuite/gdc.test/fail_compilation/diag19225.d
index bbb8251..a43a7e1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag19225.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag19225.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
fail_compilation/diag19225.d(14): Error: basic type expected, not `else`
fail_compilation/diag19225.d(14): There's no `static else`, use `else` instead.
fail_compilation/diag19225.d(14): Error: found `else` without a corresponding `if`, `version` or `debug` statement
-fail_compilation/diag19225.d(15): Error: unrecognized declaration
+fail_compilation/diag19225.d(15): Error: unmatched closing brace
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
index a0d245b..282665f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8101.d
@@ -13,12 +13,12 @@ fail_compilation/diag8101.d(38): `diag8101.f_2(int, int,
fail_compilation/diag8101.d(39): `diag8101.f_2(int, int, int, int)`
fail_compilation/diag8101.d(40): `diag8101.f_2(int, int, int, int, int)`
fail_compilation/diag8101.d(59): ... (1 more, -v to show) ...
-fail_compilation/diag8101.d(61): Error: template `diag8101.t_0` cannot deduce function from argument types `!()()`
+fail_compilation/diag8101.d(61): Error: none of the overloads of template `diag8101.t_0` are callable using argument types `!()()`
fail_compilation/diag8101.d(43): Candidate is: `t_0(T1)()`
-fail_compilation/diag8101.d(62): Error: template `diag8101.t_1` cannot deduce function from argument types `!()()`
+fail_compilation/diag8101.d(62): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()`
fail_compilation/diag8101.d(45): Candidates are: `t_1(T1)()`
fail_compilation/diag8101.d(46): `t_1(T1, T2)()`
-fail_compilation/diag8101.d(63): Error: template `diag8101.t_2` cannot deduce function from argument types `!()()`
+fail_compilation/diag8101.d(63): Error: none of the overloads of template `diag8101.t_2` are callable using argument types `!()()`
fail_compilation/diag8101.d(48): Candidates are: `t_2(T1)()`
fail_compilation/diag8101.d(49): `t_2(T1, T2)()`
fail_compilation/diag8101.d(50): `t_2(T1, T2, T3)()`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d
index f202fb3..a04ed7c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8648.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8648.d
@@ -2,13 +2,13 @@
TEST_OUTPUT:
---
fail_compilation/diag8648.d(18): Error: undefined identifier `X`
-fail_compilation/diag8648.d(29): Error: template `diag8648.foo` cannot deduce function from argument types `!()(Foo!(int, 1))`
+fail_compilation/diag8648.d(29): Error: none of the overloads of template `diag8648.foo` are callable using argument types `!()(Foo!(int, 1))`
fail_compilation/diag8648.d(18): Candidate is: `foo(T, n)(X!(T, n))`
fail_compilation/diag8648.d(20): Error: undefined identifier `a`
-fail_compilation/diag8648.d(31): Error: template `diag8648.bar` cannot deduce function from argument types `!()(Foo!(int, 1))`
+fail_compilation/diag8648.d(31): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, 1))`
fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))`
fail_compilation/diag8648.d(20): Error: undefined identifier `a`
-fail_compilation/diag8648.d(32): Error: template `diag8648.bar` cannot deduce function from argument types `!()(Foo!(int, f))`
+fail_compilation/diag8648.d(32): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, f))`
fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8684.d b/gcc/testsuite/gdc.test/fail_compilation/diag8684.d
index acfee71..9fbbebf 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8684.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8684.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag8684.d(11): Error: found `;` when expecting `)`
-fail_compilation/diag8684.d(12): Error: semicolon expected, not `for`
+fail_compilation/diag8684.d(12): Error: found `;` when expecting `)`
+fail_compilation/diag8684.d(13): Error: semicolon needed to end declaration of `x`, instead of `for`
+fail_compilation/diag8684.d(12): `x` declared here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d
index 62fce32..37d5bd8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag9004.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag9004.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag9004.d(21): Error: template `diag9004.bar` cannot deduce function from argument types `!()(Foo!int, int)`
+fail_compilation/diag9004.d(21): Error: none of the overloads of template `diag9004.bar` are callable using argument types `!()(Foo!int, int)`
fail_compilation/diag9004.d(14): Candidate is: `bar(FooT)(FooT foo, FooT.T x)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag9420.d b/gcc/testsuite/gdc.test/fail_compilation/diag9420.d
index 6b2577d..92cb47f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag9420.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag9420.d
@@ -1,5 +1,5 @@
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/diag9420.d(21): Error: function `diag9420.S.t3!().tx()` is not callable using argument types `(int)`
fail_compilation/diag9420.d(21): expected 0 argument(s), not 1
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diagin.d b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
index a4dabee..eb88a23 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diagin.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diagin.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
---
fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()`
fail_compilation/diagin.d(14): missing argument for parameter #1: `in int`
-fail_compilation/diagin.d(16): Error: template `diagin.foo1` cannot deduce function from argument types `!()(bool[])`
+fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])`
fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip25.d b/gcc/testsuite/gdc.test/fail_compilation/dip25.d
index 44fec37..4e803be 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/dip25.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/dip25.d
@@ -3,7 +3,7 @@ REQUIRED_ARGS: -de
TEST_OUTPUT:
---
fail_compilation/dip25.d(17): Deprecation: returning `this.buffer[]` escapes a reference to parameter `this`
-fail_compilation/dip25.d(17): perhaps annotate the parameter with `return`
+fail_compilation/dip25.d(17): perhaps annotate the function with `return`
fail_compilation/dip25.d(22): Error: returning `identity(x)` escapes a reference to local variable `x`
fail_compilation/dip25.d(23): Deprecation: returning `identity(x)` escapes a reference to parameter `x`
fail_compilation/dip25.d(23): perhaps annotate the parameter with `return`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10964.d b/gcc/testsuite/gdc.test/fail_compilation/fail10964.d
index 4b31a92..de3673f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10964.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10964.d
@@ -5,8 +5,8 @@ fail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is no
fail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow`
fail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow`
fail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(34): Error: function `core.internal.array.construction._d_arraysetctor!(S[], S)._d_arraysetctor` is not `nothrow`
-fail_compilation/fail10964.d(35): Error: function `core.internal.array.construction._d_arrayctor!(S[], S)._d_arrayctor` is not `nothrow`
+fail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow`
+fail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow`
fail_compilation/fail10964.d(22): Error: `nothrow` function `fail10964.foo` may throw
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11453a.d b/gcc/testsuite/gdc.test/fail_compilation/fail11453a.d
index 488bc6e..379e86b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail11453a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail11453a.d
@@ -1,7 +1,7 @@
// REQUIRED_ARGS: -Ifail_compilation/extra-files
// EXTRA_SOURCES: extra-files/foo11453.d extra-files/bar11453.d
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/extra-files/bar11453.d(1): Error: package name 'foo11453' conflicts with usage as a module name in file fail_compilation/extra-files/foo11453.d
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11453b.d b/gcc/testsuite/gdc.test/fail_compilation/fail11453b.d
index c9d7b96..4e99395 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail11453b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail11453b.d
@@ -1,7 +1,7 @@
// REQUIRED_ARGS: -Ifail_compilation/extra-files
// EXTRA_SOURCES: extra-files/bar11453.d extra-files/foo11453.d
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/extra-files/foo11453.d(1): Error: module `foo11453` from file fail_compilation/extra-files/foo11453.d conflicts with package name foo11453
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11653.d b/gcc/testsuite/gdc.test/fail_compilation/fail11653.d
index fa69edb..4eeb9be 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail11653.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail11653.d
@@ -1,9 +1,8 @@
-// REQUIRED_ARGS: -de
/*
TEST_OUTPUT:
---
-fail_compilation/fail11653.d(19): Deprecation: switch case fallthrough - use 'goto case;' if intended
-fail_compilation/fail11653.d(24): Deprecation: switch case fallthrough - use 'goto default;' if intended
+fail_compilation/fail11653.d(18): Error: switch case fallthrough - use 'goto case;' if intended
+fail_compilation/fail11653.d(23): Error: switch case fallthrough - use 'goto default;' if intended
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d
index 46ed9f6..2056c0e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail12744.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail12744.d
@@ -14,10 +14,10 @@ fail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L!
fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out`
fail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out`
-fail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` cannot deduce function from argument types `!(foo12744O)(int)`
+fail_compilation/fail12744.d(67): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744O)(int)`
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy`
-fail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` cannot deduce function from argument types `!(foo12744L)(int)`
+fail_compilation/fail12744.d(68): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744L)(int)`
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail132.d b/gcc/testsuite/gdc.test/fail_compilation/fail132.d
index 2c271d9..58ce8a1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail132.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail132.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail132.d(19): Error: outer class `A` `this` needed to `new` nested class `B`
+fail_compilation/fail132.d(19): Error: cannot construct nested class `B` because no implicit `this` reference to outer class `A` is available
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d
index c5ae8e7..be72663 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail14669.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail14669.d
@@ -4,7 +4,7 @@ TEST_OUTPUT:
fail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters
fail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating
fail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters
-fail_compilation/fail14669.d(17): Error: template `fail14669.foo2` cannot deduce function from argument types `!()(int)`
+fail_compilation/fail14669.d(17): Error: none of the overloads of template `fail14669.foo2` are callable using argument types `!()(int)`
fail_compilation/fail14669.d(12): Candidate is: `foo2()(auto int a)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail162.d b/gcc/testsuite/gdc.test/fail_compilation/fail162.d
index 663e0e1..a537f10 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail162.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail162.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail162.d(25): Error: template `fail162.testHelper` cannot deduce function from argument types `!()(string, string)`
+fail_compilation/fail162.d(25): Error: none of the overloads of template `fail162.testHelper` are callable using argument types `!()(string, string)`
fail_compilation/fail162.d(10): Candidate is: `testHelper(A...)()`
fail_compilation/fail162.d(30): Error: template instance `fail162.test!("hello", "world")` error instantiating
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18417.d b/gcc/testsuite/gdc.test/fail_compilation/fail18417.d
index b32a99b..7da7bd1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18417.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18417.d
@@ -1,4 +1,4 @@
-// REQUIRED_ARGS : -de
+// REQUIRED_ARGS: -de
/*
TEST_OUTPUT:
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail196.d b/gcc/testsuite/gdc.test/fail_compilation/fail196.d
index 78fc361..c7b28cf 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail196.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail196.d
@@ -1,23 +1,24 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail196.d(26): Error: delimited string must end in )"
-fail_compilation/fail196.d(26): Error: Implicit string concatenation is error-prone and disallowed in D
-fail_compilation/fail196.d(26): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\x0a assert(s == "
-fail_compilation/fail196.d(27): Error: semicolon expected, not `foo`
-fail_compilation/fail196.d(27): Error: found `");\x0a\x0a s = q"` when expecting `;` following statement
-fail_compilation/fail196.d(29): Error: found `";\x0a assert(s == "` when expecting `;` following statement
-fail_compilation/fail196.d(30): Error: found `");\x0a\x0a s = q"` when expecting `;` following statement
-fail_compilation/fail196.d(32): Error: found `{` when expecting `;` following statement
-fail_compilation/fail196.d(32): Error: found `}` when expecting `;` following statement
-fail_compilation/fail196.d(33): Error: found `foo` when expecting `;` following statement
+fail_compilation/fail196.d(27): Error: delimited string must end in )"
+fail_compilation/fail196.d(27): Error: Implicit string concatenation is error-prone and disallowed in D
+fail_compilation/fail196.d(27): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\x0a assert(s == "
+fail_compilation/fail196.d(28): Error: semicolon needed to end declaration of `s`, instead of `foo`
+fail_compilation/fail196.d(27): `s` declared here
+fail_compilation/fail196.d(28): Error: found `");\x0a\x0a s = q"` when expecting `;` following statement
+fail_compilation/fail196.d(30): Error: found `";\x0a assert(s == "` when expecting `;` following statement
+fail_compilation/fail196.d(31): Error: found `");\x0a\x0a s = q"` when expecting `;` following statement
+fail_compilation/fail196.d(33): Error: found `{` when expecting `;` following statement
fail_compilation/fail196.d(33): Error: found `}` when expecting `;` following statement
-fail_compilation/fail196.d(35): Error: found `<` when expecting `;` following statement
-fail_compilation/fail196.d(36): Error: found `foo` when expecting `;` following statement
-fail_compilation/fail196.d(36): Error: found `<` instead of statement
-fail_compilation/fail196.d(42): Error: unterminated string constant starting at fail_compilation/fail196.d(42)
-fail_compilation/fail196.d(44): Error: found `End of File` when expecting `}` following compound statement
-fail_compilation/fail196.d(44): Error: found `End of File` when expecting `}` following compound statement
+fail_compilation/fail196.d(34): Error: found `foo` when expecting `;` following statement
+fail_compilation/fail196.d(34): Error: found `}` when expecting `;` following statement
+fail_compilation/fail196.d(36): Error: found `<` when expecting `;` following statement
+fail_compilation/fail196.d(37): Error: found `foo` when expecting `;` following statement
+fail_compilation/fail196.d(37): Error: found `<` instead of statement
+fail_compilation/fail196.d(43): Error: unterminated string constant starting at fail_compilation/fail196.d(43)
+fail_compilation/fail196.d(45): Error: found `End of File` when expecting `}` following compound statement
+fail_compilation/fail196.d(45): Error: found `End of File` when expecting `}` following compound statement
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19609.d b/gcc/testsuite/gdc.test/fail_compilation/fail19609.d
index c68f199..d2e146c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19609.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19609.d
@@ -1,7 +1,7 @@
// https://issues.dlang.org/show_bug.cgi?id=19609
/*
EXTRA_FILES: imports/fail19609a.d imports/fail19609b.d imports/fail19609c.d imports/fail19609d.d
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/imports/fail19609a.d(1): Error: `string` expected for deprecation message, not `([""])` of type `string[]`
fail_compilation/fail19609.d(16): Deprecation: module `imports.fail19609a` is deprecated
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19897.d b/gcc/testsuite/gdc.test/fail_compilation/fail19897.d
index d5e6f57..4f5804b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19897.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19897.d
@@ -1,5 +1,5 @@
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/fail19897.d(9): Error: cannot implicitly convert expression `[]` of type `const(char[0])` to `const(char)`
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail207.d b/gcc/testsuite/gdc.test/fail_compilation/fail207.d
index 2a00f7f..2fec197 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail207.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail207.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail207.d(10): Error: found end of file instead of initializer
-fail_compilation/fail207.d(10): Error: semicolon expected, not `End of File`
+fail_compilation/fail207.d(11): Error: found end of file instead of initializer
+fail_compilation/fail207.d(11): Error: semicolon needed to end declaration of `x`, instead of `End of File`
+fail_compilation/fail207.d(10): `x` declared here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d
index 9320423..00dd9fd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail20730b.d
@@ -3,7 +3,7 @@ REQUIRED_ARGS: -verrors=spec -o-
TEST_OUTPUT:
---
(spec:1) fail_compilation/fail20730b.d-mixin-43(43): Error: C style cast illegal, use `cast(int)mod`
-fail_compilation/fail20730b.d(26): Error: template `fail20730b.atomicOp` cannot deduce function from argument types `!("+=")(shared(uint), int)`
+fail_compilation/fail20730b.d(26): Error: none of the overloads of template `fail20730b.atomicOp` are callable using argument types `!("+=")(shared(uint), int)`
fail_compilation/fail20730b.d(41): Candidate is: `atomicOp(string op, T, V1)(shared ref T val, V1 mod)`
with `op = "+=",
T = uint,
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21830.d b/gcc/testsuite/gdc.test/fail_compilation/fail21830.d
index 9955c65..2e0f84b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21830.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21830.d
@@ -1,5 +1,5 @@
/* REQUIRED_ARGS: -de -unittest
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/fail21830.d(24): Deprecation: struct `fail21830.OldS21830` is deprecated - Deprecated type
fail_compilation/fail21830.d(24): Deprecation: template `fail21830.test21830(T)(T t) if (is(T == OldS21830))` is deprecated - Deprecated template
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21831.d b/gcc/testsuite/gdc.test/fail_compilation/fail21831.d
index 699ef0b..3955133 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21831.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21831.d
@@ -1,5 +1,5 @@
/* REQUIRED_ARGS: -de -unittest
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/fail21831.d(19): Deprecation: struct `fail21831.S21831` is deprecated - Deprecated type
fail_compilation/fail21831.d(19): Deprecation: template `fail21831.test21831(T)(T t) if (__traits(isDeprecated, T))` is deprecated - Deprecated template
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21832.d b/gcc/testsuite/gdc.test/fail_compilation/fail21832.d
index 03753a4..98f3df7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21832.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21832.d
@@ -1,7 +1,7 @@
// REQUIRED_ARGS: -de
// EXTRA_FILES: imports/imp21832.d
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/fail21832.d(4): Deprecation: function `imports.imp21832.fun` is deprecated
fail_compilation/fail21832.d(10): Deprecation: template `imports.imp21832.tpl()(char a)` is deprecated
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail220.d b/gcc/testsuite/gdc.test/fail_compilation/fail220.d
index 294dc21..d3905d7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail220.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail220.d
@@ -5,7 +5,7 @@ fail_compilation/fail220.d(12): Error: identifier expected for template value pa
fail_compilation/fail220.d(12): Error: found `==` when expecting `)`
fail_compilation/fail220.d(12): Error: found `class` when expecting `)`
fail_compilation/fail220.d(12): Error: declaration expected, not `)`
-fail_compilation/fail220.d(16): Error: unrecognized declaration
+fail_compilation/fail220.d(16): Error: unmatched closing brace
---
*/
template types (T) {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22035.d b/gcc/testsuite/gdc.test/fail_compilation/fail22035.d
index ba03be6..2e67b4d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22035.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22035.d
@@ -1,5 +1,5 @@
// https://issues.dlang.org/show_bug.cgi?id=22035
-/* TEST_OUTPUT
+/* TEST_OUTPUT:
---
fail_compilation/fail22035.d(10): Error: found `2` when expecting `:`
fail_compilation/fail22035.d(10): Error: found `:` instead of statement
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22084.d b/gcc/testsuite/gdc.test/fail_compilation/fail22084.d
index bd11832..b0ae722 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22084.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22084.d
@@ -1,6 +1,6 @@
// https://issues.dlang.org/show_bug.cgi?id=22084
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/fail22084.d(22): Error: cannot pass types that need destruction as variadic arguments
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22133.d b/gcc/testsuite/gdc.test/fail_compilation/fail22133.d
index 338d96d..a30d430 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22133.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22133.d
@@ -1,6 +1,6 @@
// https://issues.dlang.org/show_bug.cgi?id=22133
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/fail22133.d(16): Error: `s.popFront()()` has no effect
fail_compilation/fail22133.d(17): Error: template `s.popFront()()` has no type
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22144.d b/gcc/testsuite/gdc.test/fail_compilation/fail22144.d
index e0fd5b1..694c1e9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22144.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22144.d
@@ -1,5 +1,5 @@
// https://issues.dlang.org/show_bug.cgi?id=22144
-/* TEST_OUTPUT
+/* TEST_OUTPUT:
---
fail_compilation/fail22144.d(12): Error: cannot cast expression `zarray1` of type `int[0]` to `int[0][]` since sizes don't line up
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22749.d b/gcc/testsuite/gdc.test/fail_compilation/fail22749.d
new file mode 100644
index 0000000..56ccac6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22749.d
@@ -0,0 +1,13 @@
+// EXTRA_FILES: imports/imp22749.c
+/* TEST_OUTPUT:
+---
+fail_compilation/fail22749.d(12): Error: cannot take address of bit-field `field`
+---
+*/
+import imports.imp22749;
+
+void test22749()
+{
+ S22749 s;
+ void* ptr = &s.field;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail236.d b/gcc/testsuite/gdc.test/fail_compilation/fail236.d
index f63eb21..626ec00 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail236.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail236.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/fail236.d(14): Error: undefined identifier `x`
-fail_compilation/fail236.d(22): Error: template `fail236.Templ2` cannot deduce function from argument types `!()(int)`
+fail_compilation/fail236.d(22): Error: none of the overloads of template `fail236.Templ2` are callable using argument types `!()(int)`
fail_compilation/fail236.d(12): Candidate is: `Templ2(alias a)(x)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail276.d b/gcc/testsuite/gdc.test/fail_compilation/fail276.d
index 4f9b7c3..b5a99a9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail276.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail276.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/fail276.d(19): Error: `this` has no effect
-fail_compilation/fail276.d(15): Error: `this` is only defined in non-static member functions, not `__anonclass2`
+fail_compilation/fail276.d(15): Error: cannot construct anonymous nested class because no implicit `this` reference to outer class is available
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4269e.d b/gcc/testsuite/gdc.test/fail_compilation/fail4269e.d
index c63bfac..8a95b34 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail4269e.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail4269e.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail4269e.d(10): Error: semicolon expected, not `X5`
+fail_compilation/fail4269e.d(10): Error: semicolon needed to end declaration of `Y` instead of `X5`
fail_compilation/fail4269e.d(10): Error: no identifier for declarator `X5`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail59.d b/gcc/testsuite/gdc.test/fail_compilation/fail59.d
index 8c51311..5360495 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail59.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail59.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail59.d(50): Error: outer class `C1` `this` needed to `new` nested class `C2`
+fail_compilation/fail59.d(50): Error: cannot construct nested class `C2` because no implicit `this` reference to outer class `C1` is available
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail60.d b/gcc/testsuite/gdc.test/fail_compilation/fail60.d
index ec8de0b..137dfa9 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail60.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail60.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail60.d(14): Error: `this` is only defined in non-static member functions, not `A`
+fail_compilation/fail60.d(14): Error: cannot construct nested class `B` because no implicit `this` reference to outer class `A` is available
---
*/
class A
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d
index a06dec5..235e480 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail8009.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail8009.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail8009.d(9): Error: template `fail8009.filter` cannot deduce function from argument types `!()(void)`
+fail_compilation/fail8009.d(9): Error: none of the overloads of template `fail8009.filter` are callable using argument types `!()(void)`
fail_compilation/fail8009.d(8): Candidate is: `filter(R)(scope bool delegate(ref BAD!R) func)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail95.d b/gcc/testsuite/gdc.test/fail_compilation/fail95.d
index b1f046a..7057a01 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail95.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail95.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail95.d(19): Error: template `fail95.A` cannot deduce function from argument types `!()(int)`
+fail_compilation/fail95.d(19): Error: none of the overloads of template `fail95.A` are callable using argument types `!()(int)`
fail_compilation/fail95.d(11): Candidate is: `A(alias T)(T)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix17635.d b/gcc/testsuite/gdc.test/fail_compilation/fix17635.d
deleted file mode 100644
index 27f55e0..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fix17635.d
+++ /dev/null
@@ -1,23 +0,0 @@
-/* REQUIRED_ARGS: -preview=dip1000
-TEST_OUTPUT:
----
-fail_compilation/fix17635.d(22): Error: cannot implicitly convert expression `f(& p)` of type `immutable(int)**` to `immutable(int**)`
----
-*/
-// https://issues.dlang.org/show_bug.cgi?id=17635
-// https://issues.dlang.org/show_bug.cgi?id=15660
-
-alias T = immutable int;
-
-T** f(const T** input) pure
-{
- T** output;
- return output;
-}
-
-void main()
-{
- T i;
- T* p = &i;
- immutable T** r = f(&p);
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11856_0.d b/gcc/testsuite/gdc.test/fail_compilation/ice11856_0.d
index 36bc2bd..1e51a06 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11856_0.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11856_0.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice11856_0.d(19): Error: template `ice11856_0.f` cannot deduce function from argument types `!()(int)`
+fail_compilation/ice11856_0.d(19): Error: none of the overloads of template `ice11856_0.f` are callable using argument types `!()(int)`
fail_compilation/ice11856_0.d(13): Candidates are: `f(T)(T t)`
fail_compilation/ice11856_0.d(16): `f(T)(T t)`
with `T = int`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d
index 70991ae..d2a1d1d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11856_1.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice11856_1.d(13): Error: template `ice11856_1.g` cannot deduce function from argument types `!()(A)`
+fail_compilation/ice11856_1.d(13): Error: none of the overloads of template `ice11856_1.g` are callable using argument types `!()(A)`
fail_compilation/ice11856_1.d(11): Candidate is: `g(T)(T x)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d
index 53e35a6..c64fb84 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice14130.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice14130.d
@@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/ice14130.d(10): Error: undefined identifier `Undef`
-fail_compilation/ice14130.d(14): Error: template `ice14130.foo` cannot deduce function from argument types `!()(int)`
+fail_compilation/ice14130.d(14): Error: none of the overloads of template `ice14130.foo` are callable using argument types `!()(int)`
fail_compilation/ice14130.d(10): Candidate is: `foo(R, F = Undef)(R r, F s = 0)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d
index ac4ba68..e1d7aac 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice14907.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice14907.d
@@ -6,7 +6,7 @@ fail_compilation/ice14907.d(19): while looking for match for `S!()`
fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion
fail_compilation/ice14907.d(20): while looking for match for `f!()`
fail_compilation/ice14907.d(15): Error: template `ice14907.f(int v = f)()` recursive template expansion
-fail_compilation/ice14907.d(21): Error: template `ice14907.f` cannot deduce function from argument types `!()()`
+fail_compilation/ice14907.d(21): Error: none of the overloads of template `ice14907.f` are callable using argument types `!()()`
fail_compilation/ice14907.d(15): Candidate is: `f(int v = f)()`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d
index 0715db5..f7c639d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice6538.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice6538.d
@@ -7,7 +7,7 @@
TEST_OUTPUT:
---
fail_compilation/ice6538.d(23): Error: expression `super` is not a valid template value argument
-fail_compilation/ice6538.d(28): Error: template `ice6538.D.foo` cannot deduce function from argument types `!()()`
+fail_compilation/ice6538.d(28): Error: none of the overloads of template `ice6538.D.foo` are callable using argument types `!()()`
fail_compilation/ice6538.d(23): Candidate is: `foo()()`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
index a6d84ae..00602d2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice9284.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice9284.d(14): Error: template `ice9284.C.__ctor` cannot deduce function from argument types `!()(int)`
+fail_compilation/ice9284.d(14): Error: none of the overloads of template `ice9284.C.__ctor` are callable using argument types `!()(int)`
fail_compilation/ice9284.d(12): Candidate is: `__ctor()(string)`
fail_compilation/ice9284.d(20): Error: template instance `ice9284.C.__ctor!()` error instantiating
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/imp18554.d b/gcc/testsuite/gdc.test/fail_compilation/imports/imp18554.d
deleted file mode 100644
index 9f2a855..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/imports/imp18554.d
+++ /dev/null
@@ -1,4 +0,0 @@
-struct S
-{
- private int i;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/imp22749.c b/gcc/testsuite/gdc.test/fail_compilation/imports/imp22749.c
new file mode 100644
index 0000000..7c1850e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/imp22749.c
@@ -0,0 +1,4 @@
+struct S22749
+{
+ int field : 1;
+};
diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue21936.d b/gcc/testsuite/gdc.test/fail_compilation/issue21936.d
deleted file mode 100644
index a37aa04..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/issue21936.d
+++ /dev/null
@@ -1,32 +0,0 @@
-/* REQUIRED_ARGS: -preview=dip1000 -Ifail_compilation/imports
-TEST_OUTPUT:
----
-fail_compilation/issue21936.d(15): Error: struct `issue21936s.S` variable `field` is not accessible from `@safe` code
-fail_compilation/issue21936.d(15): Error: struct `issue21936s.S` variable `field` is not accessible from `@safe` code
-fail_compilation/issue21936.d(11): Error: template instance `issue21936.constructImplicit!(S)` error instantiating
-fail_compilation/issue21936.d(7): instantiated from here: `registerConstructors!(S)`
-fail_compilation/issue21936.d(21): instantiated from here: `registerType!(S)`
----
-*/
-#line 2
-module issue21936;
-import issue21936s;
-struct Handlers {
- void registerType(T)()
- {
- registerConstructors!T;
- }
- void registerConstructors(T)()
- {
- constructImplicit!T;
- }
-}
-
-auto constructImplicit(T)(typeof(T.init.tupleof) x = T.init.tupleof)
-{
-}
-
-void registerHandlersDateTime(Handlers handlers)
-{
- handlers.registerType!(S);
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
index 4a588b4..696081a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
@@ -16,8 +16,8 @@ fail_compilation\noreturn.d(69): Error: `"Accessed expression of type `noreturn`
fail_compilation\noreturn.d(79): called from here: `casting(1)`
fail_compilation\noreturn.d(72): Error: `"Accessed expression of type `noreturn`"`
fail_compilation\noreturn.d(80): called from here: `casting(2)`
+fail_compilation/noreturn.d(120): Error: uncaught CTFE exception `object.Exception("")`
---
-
https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1034.md
*/
@@ -116,3 +116,5 @@ int inClassRef()
enum forceInClassRef = inClassRef();
*/
+
+enum throwEnum = throw new Exception("");
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
index e7d28dc..2d27d6d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
@@ -88,3 +88,54 @@ auto returnVoid3(int i)
else
return doStuff();
}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(104): Error: `object.Exception` is thrown but not caught
+fail_compilation/noreturn2.d(100): Error: `nothrow` function `noreturn2.doesNestedThrow` may throw
+---
++/
+
+int doesNestedThrow(int i) nothrow
+{
+ // Weird formatting is intended to check the loc
+ return i ? i++ :
+ throw
+ new
+ Exception("")
+ ;
+}
+
+int doesNestedThrowThrowable(int i) nothrow
+{
+ return i ? i++ : throw new Error("");
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(130): Error: cannot create instance of interface `I`
+fail_compilation/noreturn2.d(133): Error: can only throw class objects derived from `Throwable`, not type `int[]`
+fail_compilation/noreturn2.d(138): Error: undefined identifier `UnkownException`
+---
++/
+
+int throwInvalid(int i) nothrow
+{
+ static interface I {}
+ // Weird formatting is intended to check the loc
+ return
+ throw
+ new
+ I()
+ ?
+ throw
+ new
+ int[4]
+ :
+ throw
+ new
+ UnkownException("")
+ ;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/objc_class2.d b/gcc/testsuite/gdc.test/fail_compilation/objc_class2.d
index 9d6658c..b4d3cd7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/objc_class2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/objc_class2.d
@@ -1,4 +1,4 @@
-// EXTRA_OBJC_SOURCES
+// EXTRA_OBJC_SOURCES:
/*
TEST_OUTPUT:
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/objc_class3.d b/gcc/testsuite/gdc.test/fail_compilation/objc_class3.d
index f76443d..cf2480e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/objc_class3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/objc_class3.d
@@ -1,4 +1,4 @@
-// EXTRA_OBJC_SOURCES
+// EXTRA_OBJC_SOURCES:
/*
TEST_OUTPUT:
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/objc_non_objc_base.d b/gcc/testsuite/gdc.test/fail_compilation/objc_non_objc_base.d
index 6e2b078..9956212 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/objc_non_objc_base.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/objc_non_objc_base.d
@@ -1,4 +1,4 @@
-// EXTRA_OBJC_SOURCES
+// EXTRA_OBJC_SOURCES:
/*
TEST_OUTPUT:
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reg6769.d b/gcc/testsuite/gdc.test/fail_compilation/reg6769.d
index b11fac9..86e37e7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reg6769.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reg6769.d
@@ -1,5 +1,5 @@
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/reg6769.d(14): Error: reinterpreting cast from `int[]` to `int[7]*` is not supported in CTFE
fail_compilation/reg6769.d(27): called from here: `reg6769a([0, 1, 2, 3, 4, 5, 6])`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
index 43998b9..eeea28c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
@@ -115,6 +115,7 @@ fail_compilation/reserved_version.d(216): Error: version identifier `D_PIE` is r
fail_compilation/reserved_version.d(217): Error: version identifier `AVR` is reserved and cannot be set
fail_compilation/reserved_version.d(218): Error: version identifier `D_PreConditions` is reserved and cannot be set
fail_compilation/reserved_version.d(219): Error: version identifier `D_PostConditions` is reserved and cannot be set
+fail_compilation/reserved_version.d(220): Error: version identifier `D_ProfileGC` is reserved and cannot be set
---
*/
@@ -236,6 +237,7 @@ version = D_PIE;
version = AVR;
version = D_PreConditions;
version = D_PostConditions;
+version = D_ProfileGC;
// This should work though
debug = DigitalMars;
@@ -346,3 +348,4 @@ debug = MSP430;
debug = AVR;
debug = D_PreConditions;
debug = D_PostConditions;
+debug = D_ProfileGC;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
index 6333309..792ea0a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
@@ -105,6 +105,7 @@
// REQUIRED_ARGS: -version=none
// REQUIRED_ARGS: -version=D_PreConditions
// REQUIRED_ARGS: -version=D_PostConditions
+// REQUIRED_ARGS: -version=D_ProfileGC
// REQUIRED_ARGS: -debug=DigitalMars
// REQUIRED_ARGS: -debug=GNU
// REQUIRED_ARGS: -debug=LDC
@@ -207,6 +208,7 @@
// REQUIRED_ARGS: -debug=none
// REQUIRED_ARGS: -debug=D_PreConditions
// REQUIRED_ARGS: -debug=D_PostConditions
+// REQUIRED_ARGS: -debug=D_ProfileGC
/*
TEST_OUTPUT:
---
@@ -315,5 +317,6 @@ Error: version identifier `all` is reserved and cannot be set
Error: version identifier `none` is reserved and cannot be set
Error: version identifier `D_PreConditions` is reserved and cannot be set
Error: version identifier `D_PostConditions` is reserved and cannot be set
+Error: version identifier `D_ProfileGC` is reserved and cannot be set
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope5.d b/gcc/testsuite/gdc.test/fail_compilation/retscope5.d
index 1f9906e..0625d8e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope5.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope5.d
@@ -5,7 +5,7 @@ REQUIRED_ARGS: -preview=dip1000
/*
TEST_OUTPUT:
---
-fail_compilation/retscope5.d(5010): Error: reference `t` assigned to `p` with longer lifetime
+fail_compilation/retscope5.d(5010): Error: address of variable `t` assigned to `p` with longer lifetime
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15191.d b/gcc/testsuite/gdc.test/fail_compilation/test15191.d
index 1b3078f..fea9fb7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15191.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15191.d
@@ -1,5 +1,5 @@
/* TEST_OUTPUT:
-PERMUTE_ARGS -dip1000
+PERMUTE_ARGS: -dip1000
---
fail_compilation/test15191.d(31): Error: returning `&identity(x)` escapes a reference to local variable `x`
fail_compilation/test15191.d(37): Error: returning `&identityPtr(x)` escapes a reference to local variable `x`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16188.d b/gcc/testsuite/gdc.test/fail_compilation/test16188.d
index 38219e9..87c55ea 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16188.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16188.d
@@ -2,7 +2,7 @@ TEST_OUTPUT:
---
fail_compilation/test16188.d(1): Error: no identifier for declarator `TEST_OUTPUT`
fail_compilation/test16188.d(1): Error: declaration expected, not `:`
-fail_compilation/test16188.d(18): Error: unrecognized declaration
+fail_compilation/test16188.d(18): Error: unmatched closing brace
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16589.d b/gcc/testsuite/gdc.test/fail_compilation/test16589.d
index 7b1f14f..0e86081 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16589.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16589.d
@@ -3,9 +3,9 @@ REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/test16589.d(26): Error: returning `&this.data` escapes a reference to parameter `this`
-fail_compilation/test16589.d(26): perhaps annotate the parameter with `return`
+fail_compilation/test16589.d(26): perhaps annotate the function with `return`
fail_compilation/test16589.d(31): Error: returning `&this` escapes a reference to parameter `this`
-fail_compilation/test16589.d(31): perhaps annotate the parameter with `return`
+fail_compilation/test16589.d(31): perhaps annotate the function with `return`
fail_compilation/test16589.d(37): Error: returning `&s.data` escapes a reference to parameter `s`
fail_compilation/test16589.d(37): perhaps annotate the parameter with `return`
fail_compilation/test16589.d(42): Error: returning `&s` escapes a reference to parameter `s`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17284.d b/gcc/testsuite/gdc.test/fail_compilation/test17284.d
index a0ea05b..ef19a56 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17284.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17284.d
@@ -2,7 +2,7 @@ TEST_OUTPUT:
---
fail_compilation/test17284.d(1): Error: no identifier for declarator `TEST_OUTPUT`
fail_compilation/test17284.d(1): Error: declaration expected, not `:`
-fail_compilation/test17284.d(12): Error: unrecognized declaration
+fail_compilation/test17284.d(12): Error: unmatched closing brace
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17450.d b/gcc/testsuite/gdc.test/fail_compilation/test17450.d
index 6d0e25a..f350cbd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17450.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17450.d
@@ -5,7 +5,7 @@ TEST_OUTPUT:
fail_compilation/test17450.d(17): Error: returning `&s.bar` escapes a reference to parameter `s`
fail_compilation/test17450.d(17): perhaps annotate the parameter with `return`
fail_compilation/test17450.d(20): Error: returning `&this.bar` escapes a reference to parameter `this`
-fail_compilation/test17450.d(20): perhaps annotate the parameter with `return`
+fail_compilation/test17450.d(20): perhaps annotate the function with `return`
---
*/
// https://issues.dlang.org/show_bug.cgi?id=17450
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18554.d b/gcc/testsuite/gdc.test/fail_compilation/test18554.d
deleted file mode 100644
index acbda50..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/test18554.d
+++ /dev/null
@@ -1,24 +0,0 @@
-/* REQUIRED_ARGS: -preview=dip1000
-EXTRA_FILES: imports/imp18554.d
-TEST_OUTPUT:
----
-fail_compilation/test18554.d(16): Error: struct `imp18554.S` variable `i` is not accessible from `@safe` code
----
-*/
-
-// https://issues.dlang.org/show_bug.cgi?id=18554
-
-import imports.imp18554;
-
-void test1() @safe
-{
- S s;
- s.tupleof[0] = 1;
-}
-
-void test2()
-{
- S s;
- s.tupleof[0] = 1;
-}
-
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19107.d b/gcc/testsuite/gdc.test/fail_compilation/test19107.d
index 98858b4..93d86bf 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test19107.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test19107.d
@@ -2,7 +2,7 @@
EXTRA_FILES: imports/imp19661.d imports/test19107a.d imports/test19107b.d
TEST_OUTPUT:
---
-fail_compilation/test19107.d(24): Error: template `test19107.all` cannot deduce function from argument types `!((c) => c)(string[])`
+fail_compilation/test19107.d(24): Error: none of the overloads of template `test19107.all` are callable using argument types `!((c) => c)(string[])`
fail_compilation/test19107.d(18): Candidate is: `all(alias pred, T)(T t)`
with `pred = __lambda2,
T = string[]`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19193.d b/gcc/testsuite/gdc.test/fail_compilation/test19193.d
index 9022776..e75d90e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test19193.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test19193.d
@@ -1,6 +1,6 @@
/*
REQUIRED_ARGS: -de
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/test19193.d(13): Deprecation: enum member `test19193.T19193!int.A.b` is deprecated
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21912.d b/gcc/testsuite/gdc.test/fail_compilation/test21912.d
index 8dde98a..5bb92a3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21912.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21912.d
@@ -1,6 +1,6 @@
/*
PERMUTE_ARGS: -preview=dip1000
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/test21912.d(24): Error: function `test21912.escapeParam` is `@nogc` yet allocates closures with the GC
fail_compilation/test21912.d(26): test21912.escapeParam.__lambda2 closes over variable i at fail_compilation/test21912.d(24)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22298.d b/gcc/testsuite/gdc.test/fail_compilation/test22298.d
new file mode 100644
index 0000000..cdb1a3e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22298.d
@@ -0,0 +1,30 @@
+/*
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test22298.d(18): Error: scope variable `i` assigned to `p` with longer lifetime
+fail_compilation/test22298.d(29): Error: scope variable `y` assigned to `x` with longer lifetime
+---
+*/
+
+void g(scope void delegate(scope int*) @safe cb) @safe {
+ int x = 42;
+ cb(&x);
+}
+
+void main() @safe {
+ int* p;
+ void f(scope int* i) @safe {
+ p = i;
+ }
+
+ g(&f);
+ // address of x has escaped g
+ assert(*p == 42);
+}
+
+void f() @safe {
+ mixin("scope int* x;");
+ scope int* y;
+ x = y;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22541.d b/gcc/testsuite/gdc.test/fail_compilation/test22541.d
new file mode 100644
index 0000000..910db0a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22541.d
@@ -0,0 +1,18 @@
+/* REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test22541.d(104): Error: returning `i` escapes a reference to parameter `i`
+fail_compilation/test22541.d(104): perhaps annotate the parameter with `return`
+---
+ */
+
+/* https://issues.dlang.org/show_bug.cgi?id=22541
+ */
+
+#line 100
+
+@safe
+ref int newe(ref return scope int i) // ref, error
+{
+ return i;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22709.d b/gcc/testsuite/gdc.test/fail_compilation/test22709.d
new file mode 100644
index 0000000..dd5258e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22709.d
@@ -0,0 +1,29 @@
+/*
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test22709.d(15): Error: address of variable `local` assigned to `arr` with longer lifetime
+fail_compilation/test22709.d(20): Error: address of variable `local` assigned to `arr` with longer lifetime
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=22709
+@safe:
+
+void escape(ref ubyte[] arr, ref ubyte[64] local)
+{
+ arr = local[];
+}
+
+void escape1(ref ubyte[64] local, ref ubyte[] arr)
+{
+ arr = local[];
+}
+
+ubyte[] getArr()
+{
+ ubyte[64] blob;
+ ubyte[] arr;
+ escape(arr, blob[]);
+ return arr;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test3818.d b/gcc/testsuite/gdc.test/fail_compilation/test3818.d
new file mode 100644
index 0000000..c66db85
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test3818.d
@@ -0,0 +1,27 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/test3818.d(104): Error: missing `; expression` before `)` of `foreach`
+fail_compilation/test3818.d(104): perhaps the `;` goes before `a`
+fail_compilation/test3818.d(109): Error: missing `; expression` before `)` of `foreach`
+fail_compilation/test3818.d(109): perhaps the `;` goes before `c`
+fail_compilation/test3818.d(110): Error: declaration expected, not `{`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=3818
+
+#line 100
+
+void test1()
+{
+ int[10] a;
+ foreach (i, x, a)
+ {
+ }
+}
+
+static foreach (a, b, c)
+{
+}
+
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test9701.d b/gcc/testsuite/gdc.test/fail_compilation/test9701.d
index 384c514..a0310c4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test9701.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test9701.d
@@ -1,5 +1,5 @@
/*
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/test9701.d(38): Error: `@safe` is not a valid attribute for enum members
fail_compilation/test9701.d(39): Error: `@system` is not a valid attribute for enum members
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test9701b.d b/gcc/testsuite/gdc.test/fail_compilation/test9701b.d
index 16c2541..725a4cd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test9701b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test9701b.d
@@ -1,6 +1,6 @@
/*
REQUIRED_ARGS: -de
-TEST_OUTPUT
+TEST_OUTPUT:
---
fail_compilation/test9701b.d(20): Deprecation: enum member `test9701b.Enum.e0` is deprecated
fail_compilation/test9701b.d(21): Deprecation: enum member `test9701b.Enum.e1` is deprecated - message
diff --git a/gcc/testsuite/gdc.test/fail_compilation/traits_parameters.d b/gcc/testsuite/gdc.test/fail_compilation/traits_parameters.d
new file mode 100644
index 0000000..5021c54
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/traits_parameters.d
@@ -0,0 +1,10 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/traits_parameters.d(9): Error: `__traits(parameters)` cannot have arguments, but `234` was supplied
+fail_compilation/traits_parameters.d(10): Error: `__traits(parameters)` may only be used inside a function
+---
+*/
+
+typeof(__traits(parameters, 234)) xyz;
+typeof(__traits(parameters)) x;
diff --git a/gcc/testsuite/gdc.test/runnable/a18.d b/gcc/testsuite/gdc.test/runnable/a18.d
index f568982..c8ed60d 100644
--- a/gcc/testsuite/gdc.test/runnable/a18.d
+++ b/gcc/testsuite/gdc.test/runnable/a18.d
@@ -1,5 +1,5 @@
/*
-COMPILE_SEPARATELY
+COMPILE_SEPARATELY:
EXTRA_SOURCES: imports/a18a.d
PERMUTE_ARGS:
RUN_OUTPUT:
diff --git a/gcc/testsuite/gdc.test/runnable/a19.d b/gcc/testsuite/gdc.test/runnable/a19.d
index 574f95ca..3681d97 100644
--- a/gcc/testsuite/gdc.test/runnable/a19.d
+++ b/gcc/testsuite/gdc.test/runnable/a19.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/a19a.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/b26.d b/gcc/testsuite/gdc.test/runnable/b26.d
index 54e28da..b80d072 100644
--- a/gcc/testsuite/gdc.test/runnable/b26.d
+++ b/gcc/testsuite/gdc.test/runnable/b26.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/b26a.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/class_opCmp.d b/gcc/testsuite/gdc.test/runnable/class_opCmp.d
new file mode 100644
index 0000000..43f31ac
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/class_opCmp.d
@@ -0,0 +1,25 @@
+class A
+{
+ int x;
+ this(int a) { x = a; }
+
+ alias opCmp = Object.opCmp;
+ alias opCmp = my_cmp;
+
+ final int my_cmp(A a)
+ {
+ return x - a.x;
+ }
+}
+
+void main()
+{
+ auto a1 = new A(1);
+ auto a2 = new A(2);
+ A a_null = null;
+ assert(a1 > a_null);
+ assert(a_null < a1);
+ assert(!(a1 < a1));
+ assert(a1 < a2);
+ assert(a2 > a1);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/fix22624.d b/gcc/testsuite/gdc.test/runnable/fix22624.d
new file mode 100644
index 0000000..542899f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/fix22624.d
@@ -0,0 +1,19 @@
+// https://issues.dlang.org/show_bug.cgi?id=22624
+// EXTRA_FILES: imports/imp22624.c
+
+import core.stdc.stdio;
+import imports.imp22624;
+
+struct S
+{
+ B b;
+ ulong y = 0x1234_0000_5678;
+}
+
+int main()
+{
+ S s;
+ //printf("%llx\n", s.y);
+ assert(s.y == 0x1234_0000_5678);
+ return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/ice15138.d b/gcc/testsuite/gdc.test/runnable/ice15138.d
index 14d6bfb..95b8c27 100644
--- a/gcc/testsuite/gdc.test/runnable/ice15138.d
+++ b/gcc/testsuite/gdc.test/runnable/ice15138.d
@@ -1,6 +1,6 @@
// EXTRA_SOURCES: imports/ice15138a.d
// PERMUTE_ARGS: -unittest -inline
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
import imports.ice15138a;
diff --git a/gcc/testsuite/gdc.test/runnable/ice15176.d b/gcc/testsuite/gdc.test/runnable/ice15176.d
index 357207d..b47b4ec 100644
--- a/gcc/testsuite/gdc.test/runnable/ice15176.d
+++ b/gcc/testsuite/gdc.test/runnable/ice15176.d
@@ -1,5 +1,5 @@
// EXTRA_SOURCES: imports/ice15176a.d imports/ice15176b.d
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
import imports.ice15176a;
diff --git a/gcc/testsuite/gdc.test/runnable/ice15200.d b/gcc/testsuite/gdc.test/runnable/ice15200.d
index b4e2cc3..2e1abbe 100644
--- a/gcc/testsuite/gdc.test/runnable/ice15200.d
+++ b/gcc/testsuite/gdc.test/runnable/ice15200.d
@@ -1,5 +1,5 @@
// EXTRA_SOURCES: imports/ice15200a.d imports/ice15200b.d
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
module ice15200;
diff --git a/gcc/testsuite/gdc.test/runnable/imports/imp22624.c b/gcc/testsuite/gdc.test/runnable/imports/imp22624.c
new file mode 100644
index 0000000..ea726d3
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/imports/imp22624.c
@@ -0,0 +1,6 @@
+
+struct B
+{
+ unsigned int x : 1;
+// unsigned int x;
+};
diff --git a/gcc/testsuite/gdc.test/runnable/issue16995.d b/gcc/testsuite/gdc.test/runnable/issue16995.d
index 3b028d4..0d59882 100644
--- a/gcc/testsuite/gdc.test/runnable/issue16995.d
+++ b/gcc/testsuite/gdc.test/runnable/issue16995.d
@@ -1,5 +1,5 @@
// REQUIRED_ARGS: -unittest
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/module_with_tests.d imports/another_module_with_tests.d
import imports.module_with_tests;
diff --git a/gcc/testsuite/gdc.test/runnable/link10425.d b/gcc/testsuite/gdc.test/runnable/link10425.d
index 95faf6f..d082516 100644
--- a/gcc/testsuite/gdc.test/runnable/link10425.d
+++ b/gcc/testsuite/gdc.test/runnable/link10425.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/bug10425.d
import imports.bug10425;
diff --git a/gcc/testsuite/gdc.test/runnable/link11069b.d b/gcc/testsuite/gdc.test/runnable/link11069b.d
index 658f46e..33992d1 100644
--- a/gcc/testsuite/gdc.test/runnable/link11069b.d
+++ b/gcc/testsuite/gdc.test/runnable/link11069b.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/link11069x.d
// EXTRA_SOURCES: imports/link11069y.d
// EXTRA_SOURCES: imports/link11069z.d
diff --git a/gcc/testsuite/gdc.test/runnable/link11395.d b/gcc/testsuite/gdc.test/runnable/link11395.d
index fe25be1..160225e 100644
--- a/gcc/testsuite/gdc.test/runnable/link11395.d
+++ b/gcc/testsuite/gdc.test/runnable/link11395.d
@@ -1,6 +1,6 @@
// EXTRA_SOURCES: imports/link11395a.d
// PERMUTE_ARGS:
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
module link11395;
import imports.link11395a;
diff --git a/gcc/testsuite/gdc.test/runnable/link12010.d b/gcc/testsuite/gdc.test/runnable/link12010.d
index 49c4eb1..fc838d8 100644
--- a/gcc/testsuite/gdc.test/runnable/link12010.d
+++ b/gcc/testsuite/gdc.test/runnable/link12010.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/a12010.d
// EXTRA_FILES: imports/std12010container.d
// REQUIRED_ARGS: -release
diff --git a/gcc/testsuite/gdc.test/runnable/link13394.d b/gcc/testsuite/gdc.test/runnable/link13394.d
index aea8686..8af0d36 100644
--- a/gcc/testsuite/gdc.test/runnable/link13394.d
+++ b/gcc/testsuite/gdc.test/runnable/link13394.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/link13394a.d
module link13394;
diff --git a/gcc/testsuite/gdc.test/runnable/link13400.d b/gcc/testsuite/gdc.test/runnable/link13400.d
index fbb9ec7..3fc4dfb 100644
--- a/gcc/testsuite/gdc.test/runnable/link13400.d
+++ b/gcc/testsuite/gdc.test/runnable/link13400.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/link13400a.d
import imports.link13400a;
diff --git a/gcc/testsuite/gdc.test/runnable/link13415.d b/gcc/testsuite/gdc.test/runnable/link13415.d
index 782bb6b..000ece3 100644
--- a/gcc/testsuite/gdc.test/runnable/link13415.d
+++ b/gcc/testsuite/gdc.test/runnable/link13415.d
@@ -2,7 +2,7 @@
EXTRA_SOURCES: imports/link13415a.d
REQUIRED_ARGS: -inline
PERMUTE_ARGS: -allinst -unittest -debug
-COMPILE_SEPARATELY
+COMPILE_SEPARATELY:
RUN_OUTPUT:
---
i = 77;
diff --git a/gcc/testsuite/gdc.test/runnable/link14588.d b/gcc/testsuite/gdc.test/runnable/link14588.d
index 2ca4b52..cfc8157 100644
--- a/gcc/testsuite/gdc.test/runnable/link14588.d
+++ b/gcc/testsuite/gdc.test/runnable/link14588.d
@@ -1,6 +1,6 @@
// EXTRA_SOURCES: imports/link14588a.d
// PERMUTE_ARGS: -allinst -unittest -debug -inline
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
import imports.link14588a;
diff --git a/gcc/testsuite/gdc.test/runnable/link14814.d b/gcc/testsuite/gdc.test/runnable/link14814.d
index ed06500..10b6b6d 100644
--- a/gcc/testsuite/gdc.test/runnable/link14814.d
+++ b/gcc/testsuite/gdc.test/runnable/link14814.d
@@ -1,6 +1,6 @@
// EXTRA_SOURCES: imports/link14814a.d
// PERMUTE_ARGS: -inline -release -g -O -fPIC
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
import imports.link14814a;
diff --git a/gcc/testsuite/gdc.test/runnable/link15017.d b/gcc/testsuite/gdc.test/runnable/link15017.d
index 16187a8..5d39547 100644
--- a/gcc/testsuite/gdc.test/runnable/link15017.d
+++ b/gcc/testsuite/gdc.test/runnable/link15017.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/std15017variant.d
/*
TEST_OUTPUT:
diff --git a/gcc/testsuite/gdc.test/runnable/link7745.d b/gcc/testsuite/gdc.test/runnable/link7745.d
index 9a0eccf..a0fdad5 100644
--- a/gcc/testsuite/gdc.test/runnable/link7745.d
+++ b/gcc/testsuite/gdc.test/runnable/link7745.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/link7745b.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/link8023.d b/gcc/testsuite/gdc.test/runnable/link8023.d
index d4c32cb..e92b150 100644
--- a/gcc/testsuite/gdc.test/runnable/link8023.d
+++ b/gcc/testsuite/gdc.test/runnable/link8023.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/link8023b.d
// PERMUTE_ARGS: -inline -release
diff --git a/gcc/testsuite/gdc.test/runnable/link9571.d b/gcc/testsuite/gdc.test/runnable/link9571.d
index 1efdbdd..caa9c78 100644
--- a/gcc/testsuite/gdc.test/runnable/link9571.d
+++ b/gcc/testsuite/gdc.test/runnable/link9571.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/link9571a.d
import imports.link9571a;
diff --git a/gcc/testsuite/gdc.test/runnable/linktypeinfo.d b/gcc/testsuite/gdc.test/runnable/linktypeinfo.d
index 04579a2..508e094 100644
--- a/gcc/testsuite/gdc.test/runnable/linktypeinfo.d
+++ b/gcc/testsuite/gdc.test/runnable/linktypeinfo.d
@@ -1,6 +1,6 @@
// EXTRA_SOURCES: imports/linktypeinfo_file.d
// PERMUTE_ARGS: -g -inline -unittest -debug
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
import imports.linktypeinfo_file;
diff --git a/gcc/testsuite/gdc.test/runnable/noreturn1.d b/gcc/testsuite/gdc.test/runnable/noreturn1.d
index 1da0479..7d15b54 100644
--- a/gcc/testsuite/gdc.test/runnable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/runnable/noreturn1.d
@@ -112,10 +112,162 @@ void test3()
}
}
+/*****************************************/
+
+Exception collectException(void function() f)
+{
+ try
+ {
+ f();
+ return null;
+ }
+ catch (Exception e)
+ return e;
+}
+
+
+int return_()
+{
+ return throw new Exception("Return");
+}
+
+void ternary(int i)
+{
+ i > 0 ? i++ : throw new Exception("Ternary");
+}
+
+void call()
+{
+ ternary(throw new Exception("Call"));
+}
+
+void arrayLiteral()
+{
+ int[] arr = [
+ 1,
+ throw new Exception("ArrayLiteral"),
+ 2
+ ];
+}
+
+void assocArrayLiteral()
+{
+ int[string] arr = [
+ "A": 1,
+ "B": throw new Exception("AssocArrayLiteral"),
+ "C": 2
+ ];
+}
+
+void testThrowExpression()
+{
+ Exception ae = collectException({ return_(); });
+ assert(ae);
+
+ ae = collectException({ ternary(1); });
+ assert(!ae);
+
+ ae = collectException({ ternary(-1); });
+ assert(ae);
+
+ ae = collectException(&call);
+ assert(ae);
+ assert(ae.msg == "Call");
+
+ ae = collectException(&arrayLiteral);
+ assert(ae);
+
+ ae = collectException(&assocArrayLiteral);
+ assert(ae);
+}
+
+
+/*****************************************/
+
+/// Verify that throws does not screw with side effects
+void testThrowSideEffect()
+{
+ static void foo(bool, void*, int) {}
+
+ bool b;
+ int i;
+
+ try
+ {
+ foo(b = true, throw new Exception(""), i++);
+ assert(false);
+ }
+ catch (Exception) {}
+
+ assert(b == true);
+ assert(i == 0);
+}
+
+/// Verify that throws does not screw with dtors
+void testThrowDtor()
+{
+ static struct S
+ {
+ __gshared int destructed;
+ int id;
+
+ ~this()
+ {
+ assert(!(destructed & id));
+ destructed |= id;
+ }
+
+ string getMessage()
+ {
+ // Force runtime dependency
+ return destructed ? "Already destructed" : "Valid";
+ }
+ }
+
+ static void fooD(S, int, S) {}
+ bool caught;
+
+ try
+ {
+ fooD(S(1), throw new Exception(S(2).getMessage()), S(4));
+ assert(false);
+ }
+ catch (Exception e)
+ {
+ caught = true;
+ assert(e.msg == "Valid");
+ }
+ assert(caught);
+ assert(S.destructed == (1 | 2));
+
+
+ static void fooC(S, int, S) {}
+ caught = false;
+ S.destructed = 0;
+
+ try
+ {
+ fooC(S(1), throw new Exception(S(2).getMessage()), S(4));
+ assert(false);
+ }
+ catch (Exception e)
+ {
+ caught = true;
+ assert(e.msg == "Valid");
+ }
+ assert(caught);
+ assert(S.destructed == (1 | 2));
+}
+
+/*****************************************/
+
int main()
{
test1();
test2();
test3();
+ testThrowExpression();
+ testThrowSideEffect();
+ testThrowDtor();
return 0;
}
diff --git a/gcc/testsuite/gdc.test/runnable/test11039.d b/gcc/testsuite/gdc.test/runnable/test11039.d
index 8c2e624..cc5cdba 100644
--- a/gcc/testsuite/gdc.test/runnable/test11039.d
+++ b/gcc/testsuite/gdc.test/runnable/test11039.d
@@ -1,5 +1,5 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test11039b.d
import imports.test11039b;
diff --git a/gcc/testsuite/gdc.test/runnable/test11239.d b/gcc/testsuite/gdc.test/runnable/test11239.d
index 9ace1cf..3420235 100644
--- a/gcc/testsuite/gdc.test/runnable/test11239.d
+++ b/gcc/testsuite/gdc.test/runnable/test11239.d
@@ -1,6 +1,6 @@
// EXTRA_SOURCES: imports/inc11239.d
// REQUIRED_ARGS: -debug
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// PERMUTE_ARGS:
import imports.inc11239;
diff --git a/gcc/testsuite/gdc.test/runnable/test11447a.d b/gcc/testsuite/gdc.test/runnable/test11447a.d
index cced477..b4e7b1f 100644
--- a/gcc/testsuite/gdc.test/runnable/test11447a.d
+++ b/gcc/testsuite/gdc.test/runnable/test11447a.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/a11447.d
// PERMUTE_ARGS: -allinst
diff --git a/gcc/testsuite/gdc.test/runnable/test11447b.d b/gcc/testsuite/gdc.test/runnable/test11447b.d
index 1e76da7..5e37a5a 100644
--- a/gcc/testsuite/gdc.test/runnable/test11447b.d
+++ b/gcc/testsuite/gdc.test/runnable/test11447b.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/b11447.d
// PERMUTE_ARGS: -allinst
diff --git a/gcc/testsuite/gdc.test/runnable/test11447c.d b/gcc/testsuite/gdc.test/runnable/test11447c.d
index ecec3e5..d3958fe 100644
--- a/gcc/testsuite/gdc.test/runnable/test11447c.d
+++ b/gcc/testsuite/gdc.test/runnable/test11447c.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/c11447.d
// REQUIRED_ARGS: -w
// PERMUTE_ARGS: -allinst -debug -g
diff --git a/gcc/testsuite/gdc.test/runnable/test11863.d b/gcc/testsuite/gdc.test/runnable/test11863.d
index f6446aa..9039fdb 100644
--- a/gcc/testsuite/gdc.test/runnable/test11863.d
+++ b/gcc/testsuite/gdc.test/runnable/test11863.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/std11863conv.d
// EXTRA_FILES: imports/std11863bitmanip.d imports/std11863format.d
diff --git a/gcc/testsuite/gdc.test/runnable/test14901.d b/gcc/testsuite/gdc.test/runnable/test14901.d
index 73a357a..599344a 100644
--- a/gcc/testsuite/gdc.test/runnable/test14901.d
+++ b/gcc/testsuite/gdc.test/runnable/test14901.d
@@ -1,7 +1,7 @@
// REQUIRED_ARGS:
// PERMUTE_ARGS: -unittest
// EXTRA_SOURCES: imports/test14901a.d imports/test14901b.d imports/test14901c.d imports/test14901d.d
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
module test14901;
diff --git a/gcc/testsuite/gdc.test/runnable/test18868.d b/gcc/testsuite/gdc.test/runnable/test18868.d
index b0085c0..26d5c66 100644
--- a/gcc/testsuite/gdc.test/runnable/test18868.d
+++ b/gcc/testsuite/gdc.test/runnable/test18868.d
@@ -1,5 +1,5 @@
/*
-COMPILE_SEPARATELY
+COMPILE_SEPARATELY:
EXTRA_SOURCES: imports/test18868_a.d imports/test18868_fls.d
PERMUTE_ARGS:
*/
diff --git a/gcc/testsuite/gdc.test/runnable/test27.d b/gcc/testsuite/gdc.test/runnable/test27.d
index b45c132..9c0a8d0 100644
--- a/gcc/testsuite/gdc.test/runnable/test27.d
+++ b/gcc/testsuite/gdc.test/runnable/test27.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test27a.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/test29.d b/gcc/testsuite/gdc.test/runnable/test29.d
index 03c81c6..5ca1eef 100644
--- a/gcc/testsuite/gdc.test/runnable/test29.d
+++ b/gcc/testsuite/gdc.test/runnable/test29.d
@@ -1,5 +1,5 @@
/*
-COMPILE_SEPARATELY
+COMPILE_SEPARATELY:
EXTRA_SOURCES: imports/test29a.d imports/test29b.d
PERMUTE_ARGS:
RUN_OUTPUT:
diff --git a/gcc/testsuite/gdc.test/runnable/test31.d b/gcc/testsuite/gdc.test/runnable/test31.d
index b19366d..ea18104 100644
--- a/gcc/testsuite/gdc.test/runnable/test31.d
+++ b/gcc/testsuite/gdc.test/runnable/test31.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test31a.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/test32.d b/gcc/testsuite/gdc.test/runnable/test32.d
index 8340ad2..d98d468 100644
--- a/gcc/testsuite/gdc.test/runnable/test32.d
+++ b/gcc/testsuite/gdc.test/runnable/test32.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test32a.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/test38.d b/gcc/testsuite/gdc.test/runnable/test38.d
index 4c76e9f..b38b9b9 100644
--- a/gcc/testsuite/gdc.test/runnable/test38.d
+++ b/gcc/testsuite/gdc.test/runnable/test38.d
@@ -1,5 +1,5 @@
/*
-COMPILE_SEPARATELY
+COMPILE_SEPARATELY:
EXTRA_SOURCES: imports/test38a.d
PERMUTE_ARGS:
RUN_OUTPUT:
diff --git a/gcc/testsuite/gdc.test/runnable/test46.d b/gcc/testsuite/gdc.test/runnable/test46.d
index 908cafb..f5089a7 100644
--- a/gcc/testsuite/gdc.test/runnable/test46.d
+++ b/gcc/testsuite/gdc.test/runnable/test46.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test46b.d imports/test46a.d imports/test46c.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/test49.d b/gcc/testsuite/gdc.test/runnable/test49.d
index 641d196..9ef1da4 100644
--- a/gcc/testsuite/gdc.test/runnable/test49.d
+++ b/gcc/testsuite/gdc.test/runnable/test49.d
@@ -1,5 +1,5 @@
/*
-COMPILE_SEPARATELY
+COMPILE_SEPARATELY:
EXTRA_SOURCES: imports/test49a.d
PERMUTE_ARGS:
RUN_OUTPUT:
diff --git a/gcc/testsuite/gdc.test/runnable/test57.d b/gcc/testsuite/gdc.test/runnable/test57.d
index 8c2b662..54cf672 100644
--- a/gcc/testsuite/gdc.test/runnable/test57.d
+++ b/gcc/testsuite/gdc.test/runnable/test57.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test57a.d imports/test57b.d
// PERMUTE_ARGS:
// REQUIRED_ARGS: -inline -release
diff --git a/gcc/testsuite/gdc.test/runnable/test7494.d b/gcc/testsuite/gdc.test/runnable/test7494.d
index 655d00a..ad9532a 100644
--- a/gcc/testsuite/gdc.test/runnable/test7494.d
+++ b/gcc/testsuite/gdc.test/runnable/test7494.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test7494a.d
// PERMUTE_ARGS:
// REQUIRED_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/test8997.d b/gcc/testsuite/gdc.test/runnable/test8997.d
index 9604e12..cc02132 100644
--- a/gcc/testsuite/gdc.test/runnable/test8997.d
+++ b/gcc/testsuite/gdc.test/runnable/test8997.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/test8997a.d
module test8997;
diff --git a/gcc/testsuite/gdc.test/runnable/testmod1.d b/gcc/testsuite/gdc.test/runnable/testmod1.d
index 6d9aa9e..43d13d0 100644
--- a/gcc/testsuite/gdc.test/runnable/testmod1.d
+++ b/gcc/testsuite/gdc.test/runnable/testmod1.d
@@ -1,4 +1,4 @@
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/testmod1a.d imports/testmod1b.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable/tls_dup.d b/gcc/testsuite/gdc.test/runnable/tls_dup.d
index e55f7e5..6acffb4 100644
--- a/gcc/testsuite/gdc.test/runnable/tls_dup.d
+++ b/gcc/testsuite/gdc.test/runnable/tls_dup.d
@@ -1,7 +1,7 @@
// NOTE: this is a dup of runnable/tls.d strictly to test the same code compiled
// separately rather than together like the original is.
-// COMPILE_SEPARATELY
+// COMPILE_SEPARATELY:
// EXTRA_SOURCES: imports/tlsa.d
// PERMUTE_ARGS:
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/cppa.d b/gcc/testsuite/gdc.test/runnable_cxx/cppa.d
index c60d6c6..cd36bf2 100644
--- a/gcc/testsuite/gdc.test/runnable_cxx/cppa.d
+++ b/gcc/testsuite/gdc.test/runnable_cxx/cppa.d
@@ -9,6 +9,9 @@
// N.B MSVC doesn't have a C++11 switch, but it defaults to the latest fully-supported standard
+// Broken for unknown reasons since the OMF => MsCOFF switch
+// DISABLED: win32omf
+
import core.stdc.stdio;
import core.stdc.stdarg;
import core.stdc.config;
diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-4.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-4.f90
new file mode 100644
index 0000000..f6cf2fd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/depend-4.f90
@@ -0,0 +1,261 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-gimple -fdump-tree-original" }
+
+! Check that 'omp depobj's depend and 'omp task/... depend' depend on
+! the same variable
+
+! For pointers, it depends on the address of the pointer target
+! For allocatable, on the allocated memory address
+
+subroutine foo(dss, dsp, dsa, daa, daaa, daap, doss, dosp, dosa, doaa, doaaa, doaap, &
+ dssv, dossv)
+ !use omp_lib
+ use iso_c_binding, only: c_intptr_t
+ implicit none (type, external)
+ integer, parameter :: omp_depend_kind = 2*c_intptr_t
+ integer :: ss, sp, sa, aa(4), aaa(:), aap(:)
+ integer :: dss, dsp, dsa, daa(4), daaa(:), daap(:)
+ integer :: doss, dosp, dosa, doaa(4), doaaa(:), doaap(:)
+ optional :: doss, dosp, dosa, doaa, doaaa, doaap
+ allocatable :: sa, aaa, dsa, daaa, dosa, doaaa
+ pointer :: sp, aap, dsp, daap, dosp, doaap
+ integer, value :: dssv, dossv
+ optional :: dossv
+
+ integer(omp_depend_kind) :: object(20)
+ integer(omp_depend_kind) :: elem(9)
+
+ !$omp depobj(object(1)) depend(in: ss)
+ !$omp depobj(object(2)) depend(in: sp)
+ !$omp depobj(object(3)) depend(in: sa)
+ !$omp depobj(object(4)) depend(in: aa)
+ !$omp depobj(object(5)) depend(in: aaa)
+ !$omp depobj(object(6)) depend(in: aap)
+ !$omp depobj(object(7)) depend(in: dss)
+ !$omp depobj(object(8)) depend(in: dsp)
+ !$omp depobj(object(9)) depend(in: dsa)
+ !$omp depobj(object(10)) depend(in: daa)
+ !$omp depobj(object(11)) depend(in: daaa)
+ !$omp depobj(object(12)) depend(in: daap)
+ !$omp depobj(object(13)) depend(in: doss)
+ !$omp depobj(object(14)) depend(in: dosp)
+ !$omp depobj(object(15)) depend(in: dosa)
+ !$omp depobj(object(16)) depend(in: doaa)
+ !$omp depobj(object(17)) depend(in: doaaa)
+ !$omp depobj(object(18)) depend(in: doaap)
+ !$omp depobj(object(19)) depend(in: dssv)
+ !$omp depobj(object(20)) depend(in: dossv)
+
+ !$omp depobj(elem(1)) depend(in: aa(2))
+ !$omp depobj(elem(2)) depend(in: aaa(2))
+ !$omp depobj(elem(3)) depend(in: aap(2))
+ !$omp depobj(elem(4)) depend(in: daa(2))
+ !$omp depobj(elem(5)) depend(in: daaa(2))
+ !$omp depobj(elem(6)) depend(in: daap(2))
+ !$omp depobj(elem(6)) depend(in: doaa(2))
+ !$omp depobj(elem(8)) depend(in: doaaa(2))
+ !$omp depobj(elem(9)) depend(in: doaap(2))
+
+ !$omp parallel
+ !$omp single
+ !$omp task depend(out: ss)
+ ss = 4
+ !$omp end task
+ !$omp task depend(out: sp)
+ sp = 4
+ !$omp end task
+ !$omp task depend(out: sa)
+ sa = 4
+ !$omp end task
+ !$omp task depend(out: aa)
+ aa = 4
+ !$omp end task
+ !$omp task depend(out: aaa)
+ aaa = 4
+ !$omp end task
+ !$omp task depend(out: aap)
+ aap = 4
+ !$omp end task
+ !$omp task depend(out: dss)
+ dss = 4
+ !$omp end task
+ !$omp task depend(out: dsp)
+ dsp = 4
+ !$omp end task
+ !$omp task depend(out: dsa)
+ dsa = 4
+ !$omp end task
+ !$omp task depend(out: daa)
+ daa = 4
+ !$omp end task
+ !$omp task depend(out: daaa)
+ daaa = 4
+ !$omp end task
+ !$omp task depend(out: daap)
+ daap = 4
+ !$omp end task
+ !$omp task depend(out: doss)
+ doss = 4
+ !$omp end task
+ !$omp task depend(out: dosp)
+ dosp = 4
+ !$omp end task
+ !$omp task depend(out: dosa)
+ dosa = 4
+ !$omp end task
+ !$omp task depend(out: doaa)
+ doaa = 4
+ !$omp end task
+ !$omp task depend(out: doaaa)
+ doaaa = 4
+ !$omp end task
+ !$omp task depend(out: doaap)
+ doaap = 4
+ !$omp end task
+ !$omp task depend(out: dossv)
+ dossv = 4
+ !$omp end task
+ !$omp task depend(out: dssv)
+ dssv = 4
+ !$omp end task
+
+ !$omp task depend(out: aa(2))
+ aa(2) = 4
+ !$omp end task
+ !$omp task depend(out: aaa(2))
+ aaa(2) = 4
+ !$omp end task
+ !$omp task depend(out: aap(2))
+ aap(2) = 4
+ !$omp end task
+ !$omp task depend(out: daa(2))
+ daa(2) = 4
+ !$omp end task
+ !$omp task depend(out: daaa(2))
+ daaa(2) = 4
+ !$omp end task
+ !$omp task depend(out: daap(2))
+ daap(2) = 4
+ !$omp end task
+ !$omp task depend(out: doaa(2))
+ doaa(2) = 4
+ !$omp end task
+ !$omp task depend(out: doaaa(2))
+ doaaa(2) = 4
+ !$omp end task
+ !$omp task depend(out: doaap(2))
+ doaap(2) = 4
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+end
+
+subroutine bar
+ implicit none (type, external)
+ integer :: depvar, x
+
+ x = 7
+ !$omp parallel
+ !$omp single
+ !$omp task depend(out: depvar)
+ x =5
+ !$omp end task
+ !$omp task depend(in: depvar)
+ if (x /= 5) stop
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+end
+
+! depvar - only used for dependency, but should still be used in depend:
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:depvar\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(in:depvar\\)" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "&object\\\[0\\\] = &ss;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[1\\\] = sp;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[2\\\] = sa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[3\\\] = &aa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[4\\\] = .integer.kind=4.\\\[0:\\\] \\* restrict\\) aaa.data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[5\\\] = .integer.kind=4.\\\[0:\\\] \\*\\) aap.data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[6\\\] = dss;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[7\\\] = \\*dsp;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[8\\\] = \\*dsa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[9\\\] = daa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[10\\\] = .integer.kind=4.\\\[0:\\\] \\* restrict\\) daaa->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[11\\\] = .integer.kind=4.\\\[0:\\\] \\*\\) daap->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[12\\\] = doss;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[13\\\] = \\*dosp;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[14\\\] = \\*dosa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[15\\\] = doaa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[16\\\] = .integer.kind=4.\\\[0:\\\] \\* restrict\\) doaaa->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[17\\\] = .integer.kind=4.\\\[0:\\\] \\*\\) doaap->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[18\\\] = &dssv;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[19\\\] = &dossv;" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "&elem\\\[0\\\] = &aa\\\[1\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[1\\\] = &\\(\\*\\(integer.kind=4.\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[2\\\] = \\(integer.kind=4. \\*\\) \\(aap.data \\+ .sizetype. \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[3\\\] = &\\(\\*daa\\)\\\[1\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[4\\\] = &\\(\\*\\(integer.kind=4.\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[5\\\] = \\(integer.kind=4. \\*\\) \\(daap->data \\+ .sizetype. \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[5\\\] = &\\(\\*doaa\\)\\\[1\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[7\\\] = &\\(\\*\\(integer.kind=4.\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[8\\\] = \\(integer.kind=4. \\*\\) \\(doaap->data \\+ .sizetype. \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\);" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:ss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*sp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*sa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:aa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) aaa.data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) aap.data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*dss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dsp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dsa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*daa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) daaa->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) daap->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*doss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dosp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dosa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*doaa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) doaaa->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) doaap->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:aa\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\) \\*\\) \\(aap.data \\+ \\(sizetype\\) \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*daa\\)\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\) \\*\\) \\(daap->data \\+ \\(sizetype\\) \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*doaa\\)\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\) \\*\\) \\(doaap->data \\+ \\(sizetype\\) \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dossv\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dssv\\)" 1 "original" } }
+
+
+! gimple dump - check only those which are simple one-line checkable:
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&ss\\) shared\\(ss\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:sp\\) shared\\(sp\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:sa\\) shared\\(sa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&aa\\) shared\\(aa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dss\\) shared\\(dss\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:daa\\) shared\\(daa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:doss\\) shared\\(doss\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:doaa\\) shared\\(doaa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&aa\\\[1\\\]\\) shared\\(aa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&dossv\\) shared\\(dossv\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&dssv\\) shared\\(dssv\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dsp;" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dsa;" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dosp;" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dosa;" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = doaaa->data;" 4 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = doaap->data;" 4 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = &\\(\\*daa\\)\\\[1\\\];" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = &\\(\\*doaa\\)\\\[1\\\];" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "= &dssv;" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "= &dossv;" 1 "gimple" } }
+
+
diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-5.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-5.f90
new file mode 100644
index 0000000..4cbe3d4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/depend-5.f90
@@ -0,0 +1,82 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
+! Check that depobj is correctly dereferenced in the depend clause.
+
+subroutine foo(dss, dsp, dsa, daa, daaa, daap, doss, dosp, dosa, doaa, doaaa, doaap)
+ !use omp_lib
+ use iso_c_binding, only: c_intptr_t
+ implicit none (type, external)
+ integer, parameter :: omp_depend_kind = 2*c_intptr_t
+ integer(omp_depend_kind) :: ss, sp, sa, aa(4), aaa(:), aap(:)
+ integer(omp_depend_kind) :: dss, dsp, dsa, daa(4), daaa(:), daap(:)
+ integer(omp_depend_kind) :: doss, dosp, dosa, doaa(4), doaaa(:), doaap(:)
+ optional :: doss, dosp, dosa, doaa, doaaa, doaap
+ allocatable :: sa, aaa, dsa, daaa, dosa, doaaa
+ pointer :: sp, aap, dsp, daap, dosp, doaap
+
+ ! Assume the depend types are initialized ...
+
+ !$omp parallel
+ !$omp single
+ !$omp task depend(depobj: ss)
+ !$omp end task
+ !$omp task depend(depobj: sp)
+ !$omp end task
+ !$omp task depend(depobj: sa)
+ !$omp end task
+ !$omp task depend(depobj: dss)
+ !$omp end task
+ !$omp task depend(depobj: dsp)
+ !$omp end task
+ !$omp task depend(depobj: dsa)
+ !$omp end task
+ !$omp task depend(depobj: doss)
+ !$omp end task
+ !$omp task depend(depobj: dosp)
+ !$omp end task
+ !$omp task depend(depobj: dosa)
+ !$omp end task
+
+ !$omp task depend(depobj: aa(2))
+ !$omp end task
+ !$omp task depend(depobj: aaa(2))
+ !$omp end task
+ !$omp task depend(depobj: aap(2))
+ !$omp end task
+ !$omp task depend(depobj: daa(2))
+ !$omp end task
+ !$omp task depend(depobj: daaa(2))
+ !$omp end task
+ !$omp task depend(depobj: daap(2))
+ !$omp end task
+ !$omp task depend(depobj: doaa(2))
+ !$omp end task
+ !$omp task depend(depobj: doaaa(2))
+ !$omp end task
+ !$omp task depend(depobj: doaap(2))
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+end
+
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:ss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*sp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*sa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*dss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dsp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dsa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*doss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dosp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dosa\\)" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:aa\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*\\(integer\\(kind=\[0-9\]+\\)\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\(integer\\(kind=\[0-9\]+\\) \\*\\) \\(aap.data \\+ \\(sizetype\\) \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*daa\\)\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*\\(integer\\(kind=\[0-9\]+\\)\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\(integer\\(kind=\[0-9\]+\\) \\*\\) \\(daap->data \\+ \\(sizetype\\) \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*doaa\\)\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*\\(integer\\(kind=\[0-9\]+\\)\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\(integer\\(kind=\[0-9\]+\\) \\*\\) \\(doaap->data \\+ \\(sizetype\\) \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\)\\)" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-6.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-6.f90
new file mode 100644
index 0000000..b6c1afe
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/depend-6.f90
@@ -0,0 +1,259 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-gimple -fdump-tree-original" }
+
+! Check that 'omp depobj's depend and 'omp task/... depend' depend on
+! the same variable
+
+! For pointers, it depends on the address of the pointer target
+! For allocatable, on the allocated memory address
+
+subroutine foo(dss, dsp, dsa, daa, daaa, daap, doss, dosp, dosa, doaa, doaaa, doaap, &
+ dssv, dossv)
+ !use omp_lib
+ use iso_c_binding, only: c_intptr_t, c_ptr, c_null_ptr
+ implicit none (type, external)
+ integer, parameter :: omp_depend_kind = 2*c_intptr_t
+ type(c_ptr) :: ss, sp, sa, aa(4), aaa(:), aap(:)
+ type(c_ptr) :: dss, dsp, dsa, daa(4), daaa(:), daap(:)
+ type(c_ptr) :: doss, dosp, dosa, doaa(4), doaaa(:), doaap(:)
+ optional :: doss, dosp, dosa, doaa, doaaa, doaap
+ allocatable :: sa, aaa, dsa, daaa, dosa, doaaa
+ pointer :: sp, aap, dsp, daap, dosp, doaap
+ type(c_ptr), value :: dssv, dossv
+ optional :: dossv
+
+ integer(omp_depend_kind) :: object(20)
+ integer(omp_depend_kind) :: elem(9)
+
+ !$omp depobj(object(1)) depend(in: ss)
+ !$omp depobj(object(2)) depend(in: sp)
+ !$omp depobj(object(3)) depend(in: sa)
+ !$omp depobj(object(4)) depend(in: aa)
+ !$omp depobj(object(5)) depend(in: aaa)
+ !$omp depobj(object(6)) depend(in: aap)
+ !$omp depobj(object(7)) depend(in: dss)
+ !$omp depobj(object(8)) depend(in: dsp)
+ !$omp depobj(object(9)) depend(in: dsa)
+ !$omp depobj(object(10)) depend(in: daa)
+ !$omp depobj(object(11)) depend(in: daaa)
+ !$omp depobj(object(12)) depend(in: daap)
+ !$omp depobj(object(13)) depend(in: doss)
+ !$omp depobj(object(14)) depend(in: dosp)
+ !$omp depobj(object(15)) depend(in: dosa)
+ !$omp depobj(object(16)) depend(in: doaa)
+ !$omp depobj(object(17)) depend(in: doaaa)
+ !$omp depobj(object(18)) depend(in: doaap)
+ !$omp depobj(object(19)) depend(in: dssv)
+ !$omp depobj(object(20)) depend(in: dossv)
+
+ !$omp depobj(elem(1)) depend(in: aa(2))
+ !$omp depobj(elem(2)) depend(in: aaa(2))
+ !$omp depobj(elem(3)) depend(in: aap(2))
+ !$omp depobj(elem(4)) depend(in: daa(2))
+ !$omp depobj(elem(5)) depend(in: daaa(2))
+ !$omp depobj(elem(6)) depend(in: daap(2))
+ !$omp depobj(elem(6)) depend(in: doaa(2))
+ !$omp depobj(elem(8)) depend(in: doaaa(2))
+ !$omp depobj(elem(9)) depend(in: doaap(2))
+
+ !$omp parallel
+ !$omp single
+ !$omp task depend(out: ss)
+ ss = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: sp)
+ sp = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: sa)
+ sa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: aa)
+ aa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: aaa)
+ aaa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: aap)
+ aap = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dss)
+ dss = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dsp)
+ dsp = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dsa)
+ dsa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: daa)
+ daa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: daaa)
+ daaa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: daap)
+ daap = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doss)
+ doss = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dosp)
+ dosp = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dosa)
+ dosa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doaa)
+ doaa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doaaa)
+ doaaa = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doaap)
+ doaap = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dossv)
+ dossv = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: dssv)
+ dssv = c_null_ptr
+ !$omp end task
+
+ !$omp task depend(out: aa(2))
+ aa(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: aaa(2))
+ aaa(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: aap(2))
+ aap(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: daa(2))
+ daa(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: daaa(2))
+ daaa(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: daap(2))
+ daap(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doaa(2))
+ doaa(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doaaa(2))
+ doaaa(2) = c_null_ptr
+ !$omp end task
+ !$omp task depend(out: doaap(2))
+ doaap(2) = c_null_ptr
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+end
+
+subroutine bar
+ implicit none (type, external)
+ integer :: depvar, x
+
+ x = 7
+ !$omp parallel
+ !$omp single
+ !$omp task depend(out: depvar)
+ x =5
+ !$omp end task
+ !$omp task depend(in: depvar)
+ if (x /= 5) stop
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+end
+
+! depvar - only used for dependency, but should still be used in depend:
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:depvar\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(in:depvar\\)" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "&object\\\[0\\\] = &ss;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[1\\\] = sp;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[2\\\] = sa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[3\\\] = &aa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[4\\\] = .void \\*\\\[0:\\\] \\* restrict\\) aaa.data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[5\\\] = .void \\*\\\[0:\\\] \\*\\) aap.data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[6\\\] = dss;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[7\\\] = \\*dsp;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[8\\\] = \\*dsa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[9\\\] = daa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[10\\\] = .void \\*\\\[0:\\\] \\* restrict\\) daaa->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[11\\\] = .void \\*\\\[0:\\\] \\*\\) daap->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[12\\\] = doss;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[13\\\] = \\*dosp;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[14\\\] = \\*dosa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[15\\\] = doaa;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[16\\\] = .void \\*\\\[0:\\\] \\* restrict\\) doaaa->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[17\\\] = .void \\*\\\[0:\\\] \\*\\) doaap->data;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[18\\\] = &dssv;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&object\\\[19\\\] = &dossv;" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "&elem\\\[0\\\] = &aa\\\[1\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[1\\\] = &\\(\\*\\(void \\*\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[2\\\] = \\(void \\* \\*\\) \\(aap.data \\+ .sizetype. \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[3\\\] = &\\(\\*daa\\)\\\[1\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[4\\\] = &\\(\\*\\(void \\*\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[5\\\] = \\(void \\* \\*\\) \\(daap->data \\+ .sizetype. \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[5\\\] = &\\(\\*doaa\\)\\\[1\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[7\\\] = &\\(\\*\\(void \\*\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "&elem\\\[8\\\] = \\(void \\* \\*\\) \\(doaap->data \\+ .sizetype. \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\);" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:ss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*sp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*sa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:aa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\*\\\[0:\\\] \\* restrict\\) aaa.data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\*\\\[0:\\\] \\*\\) aap.data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*dss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dsp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dsa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*daa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\*\\\[0:\\\] \\* restrict\\) daaa->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\*\\\[0:\\\] \\*\\) daap->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*doss\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dosp\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dosa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*doaa\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\*\\\[0:\\\] \\* restrict\\) doaaa->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\*\\\[0:\\\] \\*\\) doaap->data\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:aa\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(void \\*\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\* \\*\\) \\(aap.data \\+ \\(sizetype\\) \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*daa\\)\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(void \\*\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\* \\*\\) \\(daap->data \\+ \\(sizetype\\) \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*doaa\\)\\\[1\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(void \\*\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\]\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(void \\* \\*\\) \\(doaap->data \\+ \\(sizetype\\) \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\)\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dossv\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dssv\\)" 1 "original" } }
+
+
+! gimple dump - check only those which are simple one-line checkable:
+
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&ss\\) shared\\(ss\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:sp\\) shared\\(sp\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:sa\\) shared\\(sa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&aa\\) shared\\(aa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dss\\) shared\\(dss\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:daa\\) shared\\(daa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:doss\\) shared\\(doss\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:doaa\\) shared\\(doaa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&aa\\\[1\\\]\\) shared\\(aa\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&dossv\\) shared\\(dossv\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&dssv\\) shared\\(dssv\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dsp;" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dsa;" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dosp;" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dosa;" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = doaaa->data;" 4 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = doaap->data;" 4 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = &\\(\\*daa\\)\\\[1\\\];" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = &\\(\\*doaa\\)\\\[1\\\];" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "= &dssv;" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "= &dossv;" 1 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/pr104211.f90 b/gcc/testsuite/gfortran.dg/pr104211.f90
new file mode 100644
index 0000000..21b0a26
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104211.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! PR fortran/104211 - ICE in find_array_section
+! Contributed by G.Steinmetz
+
+program p
+ type t
+ real :: n
+ end type
+ type(t), parameter :: a(3) = [t(2)] ! { dg-error "Different shape" }
+ type(t), parameter :: b(2) = a(2:3) ! { dg-error "Error in array constructor" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr104528.f b/gcc/testsuite/gfortran.dg/pr104528.f
new file mode 100644
index 0000000..5b43feb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104528.f
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! { dg-options "-O2 -fpeel-loops -ftree-loop-vectorize -fno-tree-scev-cprop --param iv-max-considered-uses=2" }
+ REAL FUNCTION FOO(M, N, A, W)
+
+ INTEGER M, N
+
+ REAL W(*)
+ COMPLEX A(*)
+
+ INTEGER II, JI, JJ, KK, LL, MP
+
+ EXTERNAL BAR
+
+ INTEGER QUX
+ EXTERNAL QUX
+
+ CALL BAR(II)
+
+ IF (M .EQ. 0) THEN
+ IF (N .EQ. 0) THEN
+ DO 140 KK = II, II + MP
+ W(KK) = 0
+ 140 CONTINUE
+ ELSE
+ KK = II + MP
+ END IF
+
+ DO 130 JI = KK, KK + MP
+ DO 120 LL = JJ, JJ + MP
+ DO 110 KK = II, II + MP
+ W(KK) = (A(KK))
+ 110 CONTINUE
+ 120 CONTINUE
+ 130 CONTINUE
+
+ IF (W(KK) .EQ. 0) THEN
+ FOO = W(QUX(MP, W, 1))
+ END IF
+
+ END IF
+
+ RETURN
+
+ END
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 47997df..2b22a61 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-modref-tree.h"
#include "ipa-modref.h"
#include "target.h"
+#include "tree-ssa-loop-niter.h"
/* This file implements dead store elimination.
@@ -1418,6 +1419,8 @@ unsigned int
pass_dse::execute (function *fun)
{
unsigned todo = 0;
+ bool released_def = false;
+
need_eh_cleanup = BITMAP_ALLOC (NULL);
need_ab_cleanup = BITMAP_ALLOC (NULL);
auto_sbitmap live_bytes (param_dse_max_object_size);
@@ -1460,6 +1463,7 @@ pass_dse::execute (function *fun)
if (gsi_remove (&gsi, true) && need_eh_cleanup)
bitmap_set_bit (need_eh_cleanup, bb->index);
release_defs (stmt);
+ released_def = true;
}
}
if (gsi_end_p (gsi))
@@ -1481,6 +1485,7 @@ pass_dse::execute (function *fun)
}
remove_phi_node (&si, true);
removed_phi = true;
+ released_def = true;
}
else
gsi_next (&si);
@@ -1506,6 +1511,9 @@ pass_dse::execute (function *fun)
BITMAP_FREE (need_eh_cleanup);
BITMAP_FREE (need_ab_cleanup);
+ if (released_def)
+ free_numbers_of_iterations_estimates (fun);
+
return todo;
}
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 709bde6..484491f 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -2824,6 +2824,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
? VEC_UNPACK_FLOAT_HI_EXPR
: VEC_UNPACK_HI_EXPR);
+ /* Conversions between DFP and FP have no special tree code
+ but we cannot handle those since all relevant vector conversion
+ optabs only have a single mode. */
+ if (CONVERT_EXPR_CODE_P (conv_code)
+ && FLOAT_TYPE_P (TREE_TYPE (type))
+ && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (type))
+ != DECIMAL_FLOAT_TYPE_P (TREE_TYPE (conv_src_type))))
+ return false;
+
if (CONVERT_EXPR_CODE_P (conv_code)
&& (2 * TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig[0])))
== TYPE_PRECISION (TREE_TYPE (type)))
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 318d10c..9bb5097 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -1048,13 +1048,19 @@ number_of_iterations_ne (class loop *loop, tree type, affine_iv *iv,
which the loop exits immediately, and the iv does not overflow.
Also note, we prove condition 2) by checking base and final seperately
- along with condition 1) or 1'). */
+ along with condition 1) or 1'). Since we ensure the difference
+ computation of c does not wrap with cond below and the adjusted s
+ will fit a signed type as well as an unsigned we can safely do
+ this using the type of the IV if it is not pointer typed. */
+ tree mtype = type;
+ if (POINTER_TYPE_P (type))
+ mtype = niter_type;
if (!niter->control.no_overflow
&& (integer_onep (s)
- || (multiple_of_p (type, fold_convert (niter_type, iv->base), s,
- false)
- && multiple_of_p (type, fold_convert (niter_type, final), s,
- false))))
+ || (multiple_of_p (mtype, fold_convert (mtype, iv->base),
+ fold_convert (mtype, s), false)
+ && multiple_of_p (mtype, fold_convert (mtype, final),
+ fold_convert (mtype, s), false))))
{
tree t, cond, relaxed_cond = boolean_false_node;
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index 8fe0682..430875a 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -272,7 +272,7 @@ target_for_debug_bind (tree var)
/* Called via walk_tree, look for SSA_NAMEs that have already been
released. */
-static tree
+tree
find_released_ssa_name (tree *tp, int *walk_subtrees, void *data_)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data_;
diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
index 36ddea2..0085354 100644
--- a/gcc/tree-ssa.h
+++ b/gcc/tree-ssa.h
@@ -49,6 +49,7 @@ extern void init_tree_ssa (function *, int size = 0);
extern void delete_tree_ssa (function *);
extern bool tree_ssa_useless_type_conversion (tree);
extern tree tree_ssa_strip_useless_type_conversions (tree);
+extern tree find_released_ssa_name (tree *, int *, void *);
extern bool ssa_defined_default_def_p (tree t);
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index e2cc721..c6b5a06 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -4533,6 +4533,37 @@ vect_slp_convert_to_external (vec_info *vinfo, slp_tree node,
return true;
}
+/* Return true if all elements of the slice are the same. */
+bool
+vect_scalar_ops_slice::all_same_p () const
+{
+ for (unsigned int i = 1; i < length; ++i)
+ if (!operand_equal_p (op (0), op (i)))
+ return false;
+ return true;
+}
+
+hashval_t
+vect_scalar_ops_slice_hash::hash (const value_type &s)
+{
+ hashval_t hash = 0;
+ for (unsigned i = 0; i < s.length; ++i)
+ hash = iterative_hash_expr (s.op (i), hash);
+ return hash;
+}
+
+bool
+vect_scalar_ops_slice_hash::equal (const value_type &s1,
+ const compare_type &s2)
+{
+ if (s1.length != s2.length)
+ return false;
+ for (unsigned i = 0; i < s1.length; ++i)
+ if (!operand_equal_p (s1.op (i), s2.op (i)))
+ return false;
+ return true;
+}
+
/* Compute the prologue cost for invariant or constant operands represented
by NODE. */
@@ -4549,45 +4580,39 @@ vect_prologue_cost_for_slp (slp_tree node,
When all elements are the same we can use a splat. */
tree vectype = SLP_TREE_VECTYPE (node);
unsigned group_size = SLP_TREE_SCALAR_OPS (node).length ();
- unsigned num_vects_to_check;
unsigned HOST_WIDE_INT const_nunits;
unsigned nelt_limit;
+ auto ops = &SLP_TREE_SCALAR_OPS (node);
+ auto_vec<unsigned int> starts (SLP_TREE_NUMBER_OF_VEC_STMTS (node));
if (TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits)
&& ! multiple_p (const_nunits, group_size))
{
- num_vects_to_check = SLP_TREE_NUMBER_OF_VEC_STMTS (node);
nelt_limit = const_nunits;
+ hash_set<vect_scalar_ops_slice_hash> vector_ops;
+ for (unsigned int i = 0; i < SLP_TREE_NUMBER_OF_VEC_STMTS (node); ++i)
+ if (!vector_ops.add ({ ops, i * const_nunits, const_nunits }))
+ starts.quick_push (i * const_nunits);
}
else
{
/* If either the vector has variable length or the vectors
are composed of repeated whole groups we only need to
cost construction once. All vectors will be the same. */
- num_vects_to_check = 1;
nelt_limit = group_size;
+ starts.quick_push (0);
}
- tree elt = NULL_TREE;
- unsigned nelt = 0;
- for (unsigned j = 0; j < num_vects_to_check * nelt_limit; ++j)
- {
- unsigned si = j % group_size;
- if (nelt == 0)
- elt = SLP_TREE_SCALAR_OPS (node)[si];
- /* ??? We're just tracking whether all operands of a single
- vector initializer are the same, ideally we'd check if
- we emitted the same one already. */
- else if (elt != SLP_TREE_SCALAR_OPS (node)[si])
- elt = NULL_TREE;
- nelt++;
- if (nelt == nelt_limit)
- {
- record_stmt_cost (cost_vec, 1,
- SLP_TREE_DEF_TYPE (node) == vect_external_def
- ? (elt ? scalar_to_vec : vec_construct)
- : vector_load,
- NULL, vectype, 0, vect_prologue);
- nelt = 0;
- }
+ /* ??? We're just tracking whether vectors in a single node are the same.
+ Ideally we'd do something more global. */
+ for (unsigned int start : starts)
+ {
+ vect_cost_for_stmt kind;
+ if (SLP_TREE_DEF_TYPE (node) == vect_constant_def)
+ kind = vector_load;
+ else if (vect_scalar_ops_slice { ops, start, nelt_limit }.all_same_p ())
+ kind = scalar_to_vec;
+ else
+ kind = vec_construct;
+ record_stmt_cost (cost_vec, 1, kind, NULL, vectype, 0, vect_prologue);
}
}
@@ -5380,7 +5405,6 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo,
unsigned dummy;
finish_cost (scalar_target_cost_data, nullptr,
&dummy, &scalar_cost, &dummy);
- delete scalar_target_cost_data;
/* Complete the target-specific vector cost calculation. */
class vector_costs *vect_target_cost_data = init_cost (bb_vinfo, false);
@@ -5393,6 +5417,7 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo,
&& li_vector_costs[vi].first == vl);
finish_cost (vect_target_cost_data, scalar_target_cost_data,
&vec_prologue_cost, &vec_inside_cost, &vec_epilogue_cost);
+ delete scalar_target_cost_data;
delete vect_target_cost_data;
vec_outside_cost = vec_prologue_cost + vec_epilogue_cost;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index ec479d3..ddd0637 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -113,6 +113,41 @@ typedef hash_map<tree_operand_hash,
std::pair<stmt_vec_info, innermost_loop_behavior *> >
vec_base_alignments;
+/* Represents elements [START, START + LENGTH) of cyclical array OPS*
+ (i.e. OPS repeated to give at least START + LENGTH elements) */
+struct vect_scalar_ops_slice
+{
+ tree op (unsigned int i) const;
+ bool all_same_p () const;
+
+ vec<tree> *ops;
+ unsigned int start;
+ unsigned int length;
+};
+
+/* Return element I of the slice. */
+inline tree
+vect_scalar_ops_slice::op (unsigned int i) const
+{
+ return (*ops)[(i + start) % ops->length ()];
+}
+
+/* Hash traits for vect_scalar_ops_slice. */
+struct vect_scalar_ops_slice_hash : typed_noop_remove<vect_scalar_ops_slice>
+{
+ typedef vect_scalar_ops_slice value_type;
+ typedef vect_scalar_ops_slice compare_type;
+
+ static const bool empty_zero_p = true;
+
+ static void mark_deleted (value_type &s) { s.length = ~0U; }
+ static void mark_empty (value_type &s) { s.length = 0; }
+ static bool is_deleted (const value_type &s) { return s.length == ~0U; }
+ static bool is_empty (const value_type &s) { return s.length == 0; }
+ static hashval_t hash (const value_type &);
+ static bool equal (const value_type &, const compare_type &);
+};
+
/************************************************************************
SLP
************************************************************************/